一、概述
在现实中继承指的是子女继承父辈的财产。在程序中,继承描述的是事物之间的所属关系,通过继承可以让多种事物形成一种关系。
概念:多个类有共同的成员变量和成员方法,抽取到另外一个类中(父类),在让多个类去继承这个父类,我们的多个类就可以获取到父类中的成员了。
二、格式和使用
class 子类 extends 父类{}
单独的这个类称为父类,基类或者超类;这多个类可以称为子类或者派生类。
//父类:
public class Fu {
String name="张三";
int age=23;
public void show() {
System.out.println("我是show方法");
}
}
//子类:继承了父类的成员和方法
public class Zi extends Fu{
}
//测试类:子类可以直接调用父类的成员变量和方法
public class MyTest {
public static void main(String[] args) {
Zi zi = new Zi();
String name = zi.name;
int age = zi.age;
System.out.println(name);
System.out.println(age);
zi.show();
}
}
三、继承的特点
1.在java中,类只支持单继承,不允许多继承,一个类只能有一个直接父类
class A{}
class B{}
class C extends A,B{} // C类不可以同时继承A类和B类
2.多个类可以继承同一个父类(好比父亲可以多个孩子)
class A{}
class B extends A{}
class C extends A{} // 类B和类C都可以继承类A
3.多层继承是可以的(一个儿子可以有一个亲爹,也可以有一个亲爷爷)
class A{}
class B extends A{} // 类B继承类A,类B是类A的子类
class C extends B{} // 类C继承类B,类C是类B的子类,同时也是类A的子类
4.子类和父类是一个相对概念,一个子类可以是某个类的父类,也可以是另一个类的子类。
四、成员变量的特点
1.子类只能获取父类的非私有成员
子类中成员变量和父类不一样的时候,直接获取的是父类的成员变量
子类中的成员变量和父类中的成员变量名称一样,获取的是子类的成员变量。
2.在子类中访问一个变量的查找顺序(“就近原则”)
a: 在子类的方法的局部范围找,有就使用
b: 在子类的成员范围找,有就使用
c: 在父类的成员范围找,有就使用
d:如果还找不到,就报错
//父类
public class Dad {
String name="王健林";
}
//子类
public class Kid extends Dad{
String name="四葱";
public void show(){
String name="五葱";
System.out.println(name);
System.out.println(this.name);
System.out.println(super.name);
}
}
//测试类
public class MyTest {
public static void main(String[] args) {
Kid kid = new Kid();
kid.show();
}
}
/*运行结果:
五葱
四葱
王健林
*/
五、成员方法
a:当子类的方法名和父类的方法名不一样的时候
b:当子类的方法名和父类的方法名一样的时候
通过子类调用方法:
1: 先查找子类中有没有该方法,如果有就使用
2:在看父类中有没有该方法,有就使用
3: 如果没有就报错
public class ExtendDemo4{
public static void main(String[] args) {
Kid4 k = new Kid4();
k.eat();
}
}
class Dad4 {
public void eat() {
System.out.println("小酌两口");
System.out.println("去睡觉了");
}
}
class Kid4 extends Dad4 {
public void eat() {
System.out.println("好好吃饭");
}
}
/*输出结果:
好好吃饭
*/
六、方法重写
1、什么是方法重写
子类中出现了和父类中一模一样的方法声明(方法名,参数列表,返回值类型),也被称为方法覆盖,方法复写。
2、方法重写的应用:
当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法。这样,即沿袭了父类的功能,又定义了子类特有的内容。
public class Demo {
public static void main(String[] args) {
NewPhone np = new NewPhone();
np.call();
}
}
class Phone {
void call() {
System.out.println("打电话");
}
}
class NewPhone extends Phone {
@Override//表示注解,如果子类重写不对,会报错
public void call() {
System.out.println("录音");
//System.out.println("打电话");
//super.call();
}
}
七、构造方法执行顺序
1.在子类中,创建子类对象,调用子类的构造方法
2.在子类构造方法的第一行代码如果没有调用父类的构造方法,则默认调父类的无参构造方法 注意事项: 如果父类没有无参构造方法,子类如何做?
1.可以手动在父类中添加一个无参构造方法
2.利用super去调用父类的其他带参构造方法
3.可以用this去调用本类的其他构造方法
public class Demo {
public static void main(String[] args) {
//Die d = new Die();
//Zi z = new Zi(1);
Zi z1 = new Zi();
}
}
class Die {
/*public Die() {
System.out.println("我是父类无参构造");
}*/
public Die(int num) {
System.out.println("我是父类有参构造");
}
}
class Zi extends Die {
public Zi() {
//super(1);
//super();
this(1); //不会再调用父类的无参构造了
System.out.println("我是子类无参构造");
}
public Zi(int num) {
//this(1);
super(1);
//会默认调用父类无参构造
System.out.println("我是子类有参构造");
}
}
八、super和this的区别
this和super的区别
this:当前对象的引用
调用子类的成员变量
调用子类的成员方法
在子类的构造方法第一行调用子类其他构造方法
super:子类对象的父类引用
调用父类的成员变量
调用父类的成员方法
在子类的构造方法第一行调用父类的构造方法
public class Demo {
public static void main(String[] args) {
Zi z = new Zi();
z.function();
}
}
class Die {
int num = 10;
public Die() {
System.out.println("我是父类无参构造");
}
public Die(int num) {
System.out.println("我是父类有参构造");
}
public void method() {
System.out.println("我是父类的方法");
}
}
class Zi extends Die {
//int num = 30;
public Zi() {
//this(1);//第一行不调用子类其他构造或者是父类构造,默认调用父类无参构造
super();
System.out.println("我是子类无参构造");
}
public Zi(int num) {
System.out.println("我是子类有参构造");
}
public void method() {
System.out.println("我是子类的方法");
}
public void function() {
//this.num = 50;
//System.out.println(num);
//this.method();
//super.num = 40;
//super.method();
System.out.println(this.num);
}
}