java学了知识没实践,有点忘了,我在这里总结一下
1.instanceof
一个二元运算符
在下文中我省略了类A和A_Son的定义,A_Son继承自A
A_Son son=new A_Son();
if(son instanceof A)
{
System.out.println("true");
}
输出结果过true,表明A_Son类的实例化对象是A的实例。
用法:变量名A instanceof 类名B
一句话总结就是:如果该变量A实际引用的对象是类B或它的子类,即为true.
再来看一个例子:
即父类变量引用子类对象。
A a=new A_Son();
if(a instanceof A_Son)
{
System.out.println("true");
}
输出结果为true。
2.父类变量引用子类对象
(对象的自动向上转型)
类的定义
class A {
void print()
{
System.out.println(getClass()+":print");
}
}
class A_Son extends A{
void print()
{
System.out.println(getClass()+":print");
}
}
main方法中
A a=new A_Son();
a.print();
输出结果:
如果把子类中的print方法去掉呢?
class A {
void print()
{
System.out.println(getClass()+":print");
}
}
class A_Son extends A{
}
输出结果依然不变。即尽管调用的是父类的print方法,getclass获得的还是子类的属性。
现在主方法不变,类的变动如下。
class A {
int id=3;
void print()
{
System.out.println(id);
}
}
class A_Son extends A{
int id=2;
}
再来看下输出结果
震惊,这次竟然是父类的变量值了。
明明上一个程序的getclass得到的还是子类的属性。
经查阅:
当一个类继承于另一个类,子类中没有父类的方法时。用子类的对象调用方法时,会首先在子类中查找(并用子类的属性),如果子类中没有该方法,再到父类中查找。
当一个方法只在父类中定义时,调用该方法时会使用父类中的属性。
如果该方法中又调用了其他方法,那么还是按照之前的顺序,先在子类中查找(使用子类的属性),再在父类中查找(使用父类的属性)。
所以此处输出还是3,因为只在父类中定义了print。
而上面的getclass方法返回的是内存中实际对象的描绘(调用自Object)。
再来看一下如果子类覆写了父类的方法
class A {
int id=3;
void print()
{
System.out.println(id);
}
}
class A_Son extends A{
int id=2;
void print()
{
System.out.println(id);
}
}
输出结果为2.
经过实验结果验证可以得到:
如果对象通过向上自动转型为父类对象实例化,如果子类也覆写了方法,那么调用的是其实际类型(此处为子类)的方法。
关于对象向下转型的遗留问题
即你用子类对象向上转型实例化了父类对象,但此时该对象只能调用父类以及父类的父类的方法。如果需要调用子类的方法,那你得向下转型。
对象向下转型
前提:该对象是向上转型得到的才可以向下转型。
eg:
class A {
}
class A_Son extends A{
void print()
{
System.out.println(getClass()+":print");
}
}
调用print方法需要向上转型
A a=new A_Son();
A_Son a_son=(A_Son)a;
((A_Son) a).print();;
a_son.print();