属性不体现多态性 方法会体现多态性
A a = new B(); 父类引用生成子类对象一定会调用父类的不带参的构造方法A(){}
super.name 获得父类对象属性
super(name) 调用父类构造方法,必须写在第一句 this()调用本类的构造方法
实测
父类A.java package Zzx; public class A { String name = "A.name=张A"; A() { System.out.println("A() 不带参"); } A(String name) { this.name = name; System.out.println("A(String) 带参"); } public void fn() { System.out.println("A fn() A成员方法"); } }
B.java package Zzx; public class B extends A { String name = "B.name=李B"; B() { System.out.println("B() 不带参"); } B(String name) { //super(name);//把name传到A中 改变A name的zhangsan 用super关键字调用父类方法 应该是调用父类带参的构造方法 必须写在第一句 this()调用本类不带参的构造方法也必须写在第一句
this.name = name; System.out.println("B(String) 带参"); System.out.println("super.name="+super.name);//获得父类对象属性 假设这里只对下面代码的加多宝实现效果 B b2 =new B("加多宝"); 如果这段代码和 super(name);都写上 super.name不是张A 将变为王老吉或者加多宝了
对王老吉不加这段代码 } @Override public void fn()//方法重写 { System.out.println("B fn() 方法重写"); } public static void main(String[] args) { B b =new B(); b.fn(); System.out.println(b.name+" 000000000000000000 属性覆盖 ");//属性覆盖 不是重写 打印B的name A a = new B();//父类引用生成子类对象 调用了父类和子类的不带参的构造方法 System.out.println("111111111111111111"); System.out.println(a.name+" 222222222222222222"); //属性值取决于引用类型A 而不是方法B 这个和调用方法刚好相反 属性无多态性 打印A的name a.fn();//调用方法的值取决于对象 而不是引用类型 和上面的属性刚好相反 体现多态性 System.out.println("333333333333333333"); A a1 = new B("王老吉");/*不加super(name)执行A的不带参和B带参构造方法 执行A不带参也就不会改变name 加了之后执行 A和B带参构造方法 而且王老吉将传给A的A(String name) 改变A的name */ System.out.println(a1.name);/*如果上面不加super(name)将打印A的name 张A 而且执行A不带参和B带参构造方法 这里加了super(name) 打印的是王老吉 执行 A和B带参构造方法*/ a1.fn();//方法重写 System.out.println(b.name+" 000000000000000000 属性覆盖 "); B b2 =new B("加多宝"); System.out.println("!!!!!!!!!!!!!! "); System.out.println(b2.name+" 000000000000000000 属性覆盖 "); } }
super关键字两种方法:1、调用父类构造方法 必须写在第一句2、引用父类对象的属性和方法
接口用来实现 抽象类用来继承 接口可以多重继承 抽象类:什么东西是什么,描述实物的本质 接口:什么东西有什么(功能),描述实物的功能
运行B.java 结果 A() 不带参 B() 不带参 B fn() 方法重写 B.name=李B 000000000000000000 属性覆盖 A() 不带参 B() 不带参 111111111111111111 A.name=张A 222222222222222222 B fn() 方法重写 333333333333333333 A() 不带参 B(String) 带参 A.name=张A
//加super之后的结果如下 而不再是上面的结果
/*
A(String) 带参
B(String) 带参
王老吉
*/ B fn() 方法重写 B.name=李B 000000000000000000 属性覆盖
A() 不带参
B(String) 带参
super.name=A.name=张A
!!!!!!!!!!!!!!
加多宝 000000000000000000 属性覆盖
抽象类 描述抽象概念
抽象类不一定有抽象方法,抽象类不能实例化,非抽象类的 抽象类的子类 可以实例化
抽象方法不需要实体,例如 public void a() {//非抽象方法一定要实体
}
public abstract void b(); //抽象方法不能有实体
抽象类的子类可以是非抽象类 但是如果父类有抽象方法子类必须重写父类的抽象方法 否者子类也必须声明为抽象类(子类也是抽象类就可以不重新父类抽象方法)