多态:多态指的是方法具有多态,而类的属性不具备多态。多态——父类引用指向子类对象,而且子类要重写父类中的方法。
多态:java的引用变量有两种类型:一种是编译时的类型,一种是运行时的类型。编译时的类型由声明该变量时使用的类型决定,运行时的类型由赋给该变量的类型决定。如果编译时的类型和运行时的类型不一致,就会出现多态。
父类:
public class Base {
public int book = 3;
public void base()
{
System.out.println("父类的普通方法");
}
public void test()
{
System.out.println("父类中被覆盖的方法");
}
}
子类:
public class Sub extends Base{
public int book = 99;
public void test()
{
System.out.println("子类中覆盖的方法");
}
public void fun()
{
System.out.println("子类中的普通方法");
}
public static void main(String[] args)
{
//编译的类型和执行的类型一样,不会产生多态
Base b = new Base();
System.out.println(b.book);
b.base();
Sub sub = new Sub();
System.out.println(sub.book);
sub.test();
sub.fun();
//编译时和运行时的类型不一样,会产生多态
Base t = new Sub();
System.out.println(t.book);
t.test();
//t.fun();//将会出现错误,因为父类中没有这个方法,多态必须是子类重写父类中的方法
}
}
比如:Base b = new Base();//编译时的类型和运行时的类型一致,不会出现多态。
Derived d = new Derived();//编译时的类型和运行时的类型一致,不会出现多态。
Base bd = new Derived();//编译时的类型和运行时的类型不一致,故出现多态。
bd.test();//注:test()方法是在子类中重写了父类的方法,那么由于多态,访问的将是子类中重写了的方法。
但是如果子类中包含了和父类中一样的属性,这个时候用bd.book访问的是父类中的属性,因为多态只针对方法,不针对属性。
向上类型转换:子类赋给父类,系统会自动完成。例如Object c = new Person();
引用类型之间的强制类型转换:把父类强制转换成子类。而且这个父类对象必须是子类实例才行(也就是编译时类型为父类类型,而运行时是子类类型,就如上面的db)。引用类型之间的转换必须要有继承关系,否则会出错。
Object str = "Hello";//str编译类型是Object,而运行类型为String,可以进行类型转换。
String s = (String)str;
System.out.println(s);//将输出Hello
强制类型转换之前要通过instanceof来判断是否类型能够转换成功.instanceof用于判断前面的类型是否为后面类型的子类或者类的实例。
if(strPtr instanceof String){
String s = (String)strPrt;
}
总结起来,多态具有下面几个特征:
一、父类引用指向子类对象。
二、这个引用只能调用父类中定义的方法和属性。
三、如果子类中重写了父类中的一个方法,那么在调用这个方法的时候将会调用子类的方法(动态链接,动态调用)。
四、属性不能被重写(覆盖),重写只针对方法而言。