Java 继承与多态
继承一方面可以复用代码,公共的属性和行为可以放到父类中,
而子类只需要关注子类特有的就可以了;另一方面,不同子类的对象可以更为方便地被统一处理。
重写就是定义和父类一样的方法,并重新实现。
继承和多态的基本概念
1)每个类有且只有一个父类,没有声明父类的,其父类为Object,子类继承了父类非private的属性和方法,可以增加自己的属性和方法,以及重写父类的方法实现。
2)new过程中,父类先进行初始化,可通过super调用父类相应的构造方法,没有使用super的情况下,默认调用父类的默认构造方法[无参构造方法]。如果父类没有默认构造方法呢?只有其它带参数的构造方法,这个时候,它的任何子类都必须在构造方法中通过super显示调用Base的带参数构造方法,否则,Java会提示编译错误。
3)子类变量和方法与父类重名的情况下,可通过super强制访问父类的变量和方法。
4)子类对象可以赋值给父类引用变量,这叫多态;
另一种说法:一个引用变量可以引用多种实际类型对象的现象称为多态,
一个引用变量可以引用这个类与和该类的所有子类对象
实际执行调用的是子类实现,这叫动态绑定。
多态的三个必要条件:继承,重写 ,父类引用指向子类对象
子类对象赋值给父类引用变量,这叫向上转型,转型就是转换类型,向上转型就是转换为父类类型。这叫多态
子类型的对象可以赋值给父类型的引用变量,这叫向上转型,这种属于自动转换,
当向上转型之后,父类引用变量可以访问子类中属于父类的属性和方法,但是不能访问子类独有的属性和方法。
向下转型: 通过父类强制转换为子类,从而来调用子类独有的方法(向下转型,在工程中很少用到).
Base b = new Child();
Child c = (Child)b;
上面是可以的。但下面这两种方式 语法上Java不会报错,但运行时会抛出错误,错误为类型转换异常。
Base b = new Base();
Child c = (Child)b;
或是
Base b = new ChildA();
ChildB childB = (Child)b;
代码虽然能够编译成功,但是在运行的时候会报错,因为b对象是由ChildA对象向上转型得到的,只能够向下转型成ChildA对象,不能够向下转型成ChildB 对象。
一个父类的变量能不能转换为一个子类的变量,取决于这个父类引用的对象类型是不是这个子类或这个子类的子类。只有当这个对象原本就是子类对象通过向上转型得到的时候才能够成功转型。
给定一个父类的变量能不能知道它到底是不是某个子类的对象,从而安全地进行类型转换呢?
答案是可以,通过instanceof关键字,看下面代码:
public boolean canCase(Base base){
return base instanceof Child;
}
这个函数返回Base类型变量是否可以转换为Child类型,instanceof前面是变量,后面是类,返回值是boolean值,表示变量引用的对象是不是该类或其子类的对象。
向下转型示例代码:
package com.androidodm.sam; public class ConvertClass{ public static void main(String[] args) { test(new ConvertClass().new Base()); test(new ConvertClass().new ChildA()); test(new ConvertClass().new ChildB()); } public static void test(Base base){ base.print(); if(base instanceof ChildA){ ChildA chila = (ChildA)base; //向下转型 chila.funcA(); //调用ChildA类独有的方法 }else if(base instanceof ChildB){ ChildB chilb = (ChildB)base; //向下转型 chilb.funcB(); //调用ChildB类独有的方法 } } class Base { public void print() { System.out.println("Base:print"); } } class ChildA extends Base { public void print() { System.out.println("ChildA:print"); } public void funcA(){ System.out.println("ChildA"); } } class ChildB extends Base { public void print() { System.out.println("ChildB:print"); } public void funcB(){ System.out.println("ChildB"); } } } 输出结果: Base:print ChildA:print ChildA ChildB:print ChildB
备注:
评论