(1),,,向上转型,,向下转型
向上转型 :
Animal a = new Cat();//类型提升。这个类型提升我们也称为 向上转型。这个提升动作是自动完成的,把猫就提升为了动物,,这个a引用可以作为动物的引用也可以把a强转成猫
a.eat();
类型提升比如: byte a=2; int b=a; a会被提升为int类型 ,,这也是向上转型
向下转型:
//如果想要调用猫的特有方法时,如何操作?
那么就得强制将父类的引用。转成子类类型。向下转型。
Cat c = (Cat)a;
c.catchMouse();
//千万不要出现这样的操作,就是将父类对象转成子类类型。其实我们转的是父类的引用
//我们能转换的是父类引用指向了自己的子类对象时,该应用可以被提升,也可以被强制转换。
//规律:多态自始至终都是子类对象在做着变化。这里猫一会变成动物,一会又变成猫
(2),,,错误的向下转型
Animal a = new Animal(); 假设父类可以创建对象的
Cat c = (Cat)a;
这样不行,,因为你不能强制将一个动物转成猫,动物是先出现的,猫是后出现的,你把一个动物转成猫,那么动物这对象里面他不具备猫特有的方法,所以这个猫 c 是不可能调用抓老鼠的方法的,,a里面没有猫特有的方法,,你不能把以前有的东西强转换为现在的东西,,比如我要一只猫,,你给我猫是对的,但是你给我一动物,,那动物不确定是啥,他有可能是猪,,,
不能强制把 a 变成 Cat ,,,那个时候有可能还没有子类,怎么把父类变成子类呢,你就是真的有子类了,但是父类没有子类特有的功能
(3),多态中需要注意:
(a)
成员函数在多态调用时,编译看左边,运行看右边。
看代码
Fu f = new Zi(); f这个引用绑定在了ew Zi对象上
f.method1();
f.method2();
f.method3();
你编译的时候看的是f这个引用型变量所属的类Fu他里面是不是有下面调用的方法.method1(),
运行的时候看的是new Zi()这个对象所属的类Zi类里面有没有f.method1();f.method2();,有就运行子类自己的方法method1();f.method2()
(b)
class Fu
{
int num=5;
void method1()
{
System.out.println("fu method_1");
}
void method2()
{
System.out.println("fu method_2");
}
}
class Zi extends Fu
{
int num=8;
void method1()
{
System.out.println("zi method_1");
}
void method3()
{
System.out.println("zi method_3");
}
}
public class JinJhi {
/**
* @param args
*/
public static void main(String[] args) {
Fu f = new Zi(); ,父类引用指向子类对象,这里走的还是父类的
System.out.println(f.num);
Zi z = new Zi();
System.out.println(z.num);
结果是: 4,5
在多态中,成员变量的特点:num都是静态成员变量的话,也是看左边
无论编译和运行,都参考左边(引用型变量所属的类)。参考父类
new Zi(); 这个对象建立的时候,堆内存里面一产生完以后,这个对象有2个变量,一个是父类的num一个是子类的num,,,你在拿父类的引用去找这num的时候,他会先找父类的num.他有自己的num,所以找自己的了,,当父类子类出现同名变量的时候,多态Fu f = new Zi()情况下看左边的Fu f
(c)
class Fu
{
static int num = 5;
void method1()
{
System.out.println("fu method_1");
}
void method2()
{
System.out.println("fu method_2");
}
static void method4()
{
System.out.println("fu method_4");
}
}
class Zi extends Fu
{
static int num = 8;
void method1()
{
System.out.println("zi method_1");
}
void method3()
{
System.out.println("zi method_3");
}
static void method4()
{
System.out.println("zi method_4");
}
}
Fu f = new Zi();
f.method4();
Zi z = new Zi();
z.method4(); 他看的是左边那个引用性变量所属类中的内容,静态先加载不属于对象,所以调用的是父类的静态内容
结果第一个打印的是父类的方法,第二个打印的是子类的静态方法
在多态中,静态成员函数的特点:
无论编译和运行,都参考左边。
原因:method4()静态方法当你在调用的时候,建立子类对象的话,这个时候父类和子类都会加载进内存,一进内存,发现静态内容先存在了这时不需要对象,直接可以Fu .method4(); Zi.method4();
静态就是只参考那个引用所属的类,,f属于fu
|