1、继承
1、1子类能够继承父类的哪些成员?
1、1、1 public 成员
1、1、2 protected 成员
1、1、3 同一个包中:缺省访问类型的成员
1、1、4 打死不能继承private成员,但是子类可以通过调用父类的set/get方法访问
1、1、5不能继承构造函数,只能通过super()调用,具体调用哪一个,还得结合传入的参数匹配。
1、2 继承的特点:
1、2、1 父变子类必须变
1、2、2 继承是一种强耦合关系
1、2、3 向上转型:父类的引用能够指向子类对象,但父类的引用只能够访问父类的成员,对于子类自身的成员就无能为力了。
1、3 继承关键子 :extends
1、4 代码实例:
父类:
package parent_child; public class P { //成员变量 private int private1=10; protected int protected1=10; public int public1=10; int friendly1=10; //构造函数 public P() { super(); System.out.println("父类——无参——构造函数被调用"); } public P(int public1, int friendly1) { super(); this.public1 = public1; this.friendly1 = friendly1; System.out.println("父类——两个参数——构造函数被调用"); } public P(int private1, int protected1, int public1, int friendly1) { super(); this.private1 = private1; this.protected1 = protected1; this.public1 = public1; this.friendly1 = friendly1; System.out.println("父类——四个参数——构造函数被调用"); } //成员方法: public void public1() { System.out.println("父类——public——方法被调用"); } protected void protected1() { System.out.println("父类——protected——方法被调用"); } private void private1() { System.out.println("父类——private——方法被调用"); } void friendly() { System.out.println("父类——friendly——方法被调用"); } //setter and getter public int getPrivate1() { return private1; } public void setPrivate1(int private1) { this.private1 = private1; } }
子类:
package parent_child; public class C extends P { private int private_child=100; public C() { super(23,45);//子类调用父类构造函数,通过传递的参数的个数自动的调用父类的构造方法 } public C(int private_child) { super(12,13,14,15);//子类调用父类构造函数 this.private_child = private_child; } public static void main(String[] args) { C child=new C(); child.protected1(); child.protected1(); child.friendly(); //针对父类的private测试: child.setPrivate1(1000); System.out.println(child.getPrivate1()); System.out.println(child.friendly1); System.out.println(child.private_child); System.out.println(child.protected1); System.out.println(child.public1); } }
结果:
2、封装:
2、1 封装到底在干什么?
将属性私有化,通过提供公有的方法访问
2、1实例代码:
package worktest; public class WorkTest_ { private int age; private int sex;//0_男 1_女 private String name; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getSex() { return sex; } public void setSex(int sex) { this.sex = sex; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
3、多态
3、1 多态到底是什么意思?
多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。
3、2 简单总结:
指向子类的父类引用由于向上转型了,它只能访问父类中拥有的方法和属性,而对于子类中存在而父类中不存在的方法,该引用是不能使用的,尽管是重载该方法。若子类重写了父类中的某些方法,在调用该些方法的时候,必定是使用子类中定义的这些方法(动态连接、动态调用)。
3、3 实现条件:继承、重写、向上传递
3、4实现方法:
1、基于继承:
package parent_child; public class P { //成员变量 private int private1=10; protected int protected1=10; public int public1=10; int friendly1=10; //构造函数 public P() { super(); System.out.println("父类——无参——构造函数被调用"); } public P(int public1, int friendly1) { super(); this.public1 = public1; this.friendly1 = friendly1; System.out.println("父类——两个参数——构造函数被调用"); } public P(int private1, int protected1, int public1, int friendly1) { super(); this.private1 = private1; this.protected1 = protected1; this.public1 = public1; this.friendly1 = friendly1; System.out.println("父类——四个参数——构造函数被调用"); } //成员方法: public void public1() { System.out.println("父类——public——方法被调用"); } protected void protected1() { System.out.println("父类——protected——方法被调用"); } private void private1() { System.out.println("父类——private——方法被调用"); } void friendly() { System.out.println("父类——friendly——方法被调用"); } //setter and getter public int getPrivate1() { return private1; } public void setPrivate1(int private1) { this.private1 = private1; } //测试多态 public void PrintlnStr() { System.out.println("父类方法自己的方法被调用"); } }
package parent_child; public class C extends P { private int private_child=100; public C() { super(23,45);//子类调用父类构造函数,通过传递的参数的个数自动的调用父类的构造方法 } public C(int private_child) { super(12,13,14,15);//子类调用父类构造函数 this.private_child = private_child; } public void PrintlnStr() { System.out.println("子类方法自己的方法被调用"); } public static void main(String[] args) { C child=new C(); child.protected1(); child.protected1(); child.friendly(); //针对父类的private测试: child.setPrivate1(1000); System.out.println(child.getPrivate1()); System.out.println(child.friendly1); System.out.println(child.private_child); System.out.println(child.protected1); System.out.println(child.public1); //测试多态: P pc=new C(); pc.PrintlnStr(); } }
2、基于接口:
3、5 经典实例(借用一个面试题):
package worktest; class A { public String show(D obj) { return ("A and D"); } public String show(A obj) { return ("A and A"); } } class B extends A{ public String show(B obj){ return ("B and B"); } public String show(A obj){ return ("B and A"); } } class C extends B{ } class D extends B{ } public class Test1 { public static void main(String[] args) { A a1 = new A(); A a2 = new B(); B b = new B(); C c = new C(); D d = new D(); System.out.println("1--" + a1.show(b)); System.out.println("2--" + a1.show(c)); System.out.println("3--" + a1.show(d)); System.out.println("4--" + a2.show(b)); System.out.println("5--" + a2.show(c)); System.out.println("6--" + a2.show(d)); System.out.println("7--" + b.show(b)); System.out.println("8--" + b.show(c)); System.out.println("9--" + b.show(d)); } }
结果:
其实在继承链中对象方法的调用存在一个优先级:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。
当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法,但是它仍然要根据继承链中方法调用的优先级来确认方法,该优先级为:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。