好久没用java了,都快忘光了。最近为了找实习温习下java,下面记一些笔记:
1、父类子类重载函数调用问题。
class A {
public void func1() {
System.out.println("A func1 is calling.");
}
public void func2() {
func1();
}
}
class B extends A {
public void func1() {
System.out.println("B func1 is calling.");
}
public void func3() {
System.out.println("B func3 is calling.");
}
}
class C {
public static void main(String[] args) {
B b = new B();
A a = b;
callA(a);
callA(new B());
}
public static void callA(A a) {
a.func1();
a.func2();
}
}
输出:
B func1 is calling.
B func1 is calling.
B func1 is calling.
B func1 is calling.
下面是网上对于子类继承父类方法的一些解释:
系统在实现的时候,其实是为每一个类提供了一个方法表,这个表中等级了该类的所有的方法(C++不是全部,仅仅登记是虚拟方法),当对象调用方法是就从这个表中去查找,如果找到就执行,如果没有就到父类查找,以此类推;这样以来,子类就继承了全部的父类的方法;当你将子类对象转换为父类的对象时,那么该对象调用方发誓就只父类方法表开始查找,因此没有办法调用子类的方法;但是对于子类来说,方法依然存在;当你声明回子类时,方法自然就可以使用了。我的理解:子类对象b建立后,即使赋给父类对象a,其函数依然存在,只不过外接的接口变小了,例如func3就不能调用了,但调用func1时发现函数被重载会依然调用子类的函数。若要调用func3,可把a强制转换成子类B。
不过对于类里面的数据,则根据当前对象的类型来确定,例如父类A里定义了int i = 1;子类B里定义了int i = 2;则a.i值为1,b.i值为2 。但若父类定义了print(){System.out.println(i);},子类未定义,则a.print()输出1,b.print()输出1;若子类定义了print(){super.print();},则两个对象的print()都输出1;若子类也定义了print(){System.out.println(i);},则两个对象的print()都输出2,即子类中的i。
看当前作用域是在子类还是父类,来选择用子类还是父类的i。调用子类重载函数时,作用域在子类,否则在父类。
instanceof可以用来判断是否一个类实现了某个接口,也可以用它来判断一个实例对象是否属于一个类。
if(a instanceof B) {
B ba = (B) a;
ba.func3();
}
注意,若强制转换一个不属于子类的父类对象为子类,会报错的。只有a instanceof B为真才可以强制转换。子类对象给父类对象实例化不需要强制转换。
未完待续......