复用类
介绍了继承的知识,个人认为继承的核心是:导出类对象包含一个基类对象,就像是他的一个成员一样,可以发送给基类对象的消息一样可以发送给导出类对象,可以认为导出类是基类的一个子集,一个类只能继承一个基类。
多态
再来谈谈两个很重要的概念:
向上转型:如同上述所言,导出类是基类的子集,所以可以明确的说,导出类一定是一个基类,基类的声明可以指向一个导出类的对象。
向下转型:要理解这个盖帘就要知道什么叫运行时绑定,个人以为这是理解向下转型的核心思想;加入有一个基类A有一个方法F(),另有一个类B继承了这个基类A,成为了他的导出类,并重写了基类的F()方法,有如下代码:
public class A{
public void f(){
System.out.println("A");
}
}
class B extends A{
public void f(){
System.out.println("B");
}
}
class Test{
public static void main(String[] args){
A a = new B();
a.f();
}
}
可以很轻松的知道最终打印的结果是 B
这里把一个导出类B的对象指向了基类,但是它并没有丧失其在基类基础上新定义的内容,当执行到a.f()时,为甚么会打印出
B而不是A,这就是运行时绑定的内容了,所以才有了向下转型。
接口
接口中只进行方法的声明,而没有具体的定义,且默认是public类型;接口中的变量是final类型的常量。实现一个接口必须实现接口的所有方法,一个类可以实现多个接口,这解决了多继承问题。
关于接口的学习有一个关键词 "接口回调" ,从效果上来看与继承结构的向上、向下转型是相差不大的:
可以把所有实现了某个接口的类都向上转型为接口类型,这也是运行时绑定参与的内容,定义时是实现了接口的类向 "接口类型"的向上转型,当使用该对象调用某个方法时,就时通过运行时绑定进行的向下转型了。
interface Basic{
void f();
int do(int a,int b);
}
class Test{
public static void main(String[] args){
List<Basic> basic = new ArrayList<>();
basic.add(new A());
basic.add(new A());
basic.add(new B());
basic.add(new B());
basic.add(new C());
for(int i=0;i<basic.size();i++){
if(i%2==0)
basic.get(i).f();
else
basic.get(i).do(i*2,i*3);
}
}
}
class A implements Basic{
public void f(){
System.our.println("A");
}
public int do(int a,int b){
return a + b * 2;
}
}
class A implements Basic{
public void f(){
System.our.println("B");
}
public int do(int a,int b){
return (a+b*10)/2;
}
}
class C implements Basic{
public void f(){
System.our.println("C");
}
public int do(int a,int b){
return Math.pow(a,b);
}
}
当然还可以用接口完成更具代表性的案例:例如工厂模式。
内部类
内部类是对多重继承的补充,一个外部类可以包含多个内部类,每个内部类都可以继承自某个接口或者某个基类,使用内部类进行多继承的操作,相对于直接使用外部类进行多继承的优点是更强的灵活性,内部类给我的感觉是即用即定义,用完即走;但是当通过外部类事项多继承时:最直观的感受是,当一个外部类实现了多个接口时,那么这个类必定需要定义大量的方法,从阅读代码上来讲也不够顺畅;但是将这个外部类实现的多个接口拆分开来,对于每个接口都使用一个内部类去实现它呢?我自认为这样会有更好的结构;