由于父类与子类的关系为由一般到特殊的关系,因此可以:
fruit a = new apple(); //父类引用变量可以指向子类对象
因此,需要父类对象的地方可以将子类对象放过去,一个父类可以有多个子类,因此,一个父类型的对象在执行同一种方法时会出现多种被子类重写的方法情况,导致同一类型对象的同一方法出现不同的执行情况,叫做多态。多态跟设计模式联系在一起,增加了java语言的灵活性。
JAVA的引用对象有两个类型,第一个是编译型类型,由声明时决定,另一个是运行时类型,由其实际指向的对象决定。调用对象的方法时,总是呈现出运行时类型的特征。编译型类型约束了类型所能使用的方法,如开头的代码中,类型a不能调用苹果特有而水果没有的方法,如果想调用,需要:
apple test = (apple)a;
之后使用test即可使用苹果特有的方法。
对于引用变量类型转换只能在继承关系的两个类型间转换,因此会出现一种情况是父类强制转换为了子类,编译时候不会出错因为有继承关系,但运行时使用的是运行时类型会报错ClassCastException(除非父类强制转换为子类时,父类引用变量实际指向的是要转换为的子类类型才不会报错),如:
Object a = "This is String type";
System sys = (System) a;
父子类转换类型时,向上转型可以是隐含的,不需要(类型)操作符的:
apple a = new apple();
fruit b = a;
而向下转型需要(类型)操作符:
fruit f = new fruit();
apple a = (apple)f;
对于基本类型,除boolean外都能转换。
容易出错的内容:
class a
{
int n = 1;
}
class b extends a
{
int n = 2;
}
public class test
{
public static void main(String[] args)
{
a A = new a();
System.out.println(A.n); //输出1
b B = new b();
System.out.println(B.n); //输出2
a AB = B; //使AB和B都指向同一个对象
System.out.println(AB.n); //输出1
}
}
以上是因为对象B有两个nfield,所以虽然AB和B都指向同一个对象,但因为类型不同,输出了不同的同名field。
声明为子类的变量可以调用父类方法,声明为父类的对象不能调用子类特有的方法。