Java语言和C++不同 后者可以有继承,也可以没有继承,有多继承也有单继承,但是Java中只有单一继承
默认从Object继承
package a.b.c;
class A{
}
class B expends A{
public static void main(String[] a){
A a = new A();
B b = new B();
a = b; //正确 父类可以指向子类
b = a; //错误 子类不能指向父类
//例如 桌子上有一个苹果,我们可以说桌子上有一个水果,也可以说桌子上有一个苹果
//但是如果桌子上有一个梨子(也属于水果),我们不能说桌子上有一个苹果
//但是可以强制类型转换 但有风险 下面这么写是正确的
b = (B)a;
//为了排除风险 我们可以使用instanceof语句,看看那个水果是不是真的是苹果
if(a instanceof B){ //...的实例
b = (B)a;//把变量的值复制一份复制到B类型中
}
}
}
package a.b.c
class A{
public void a(){}
}
public B extends A{
public void b(){}
public static void main(String[] a){
A a=new B();
a.a();
a.b(); //这句出错了 不能通过类型检查 a是A类型的引用 而不是B类型的 不支持b()
//但是作为程序员 我们知道a实际指向的是一个B,所以我们可以强制类型转换
((B)a).b(); //注意优先级问题
}
多态
静态多态:一个对象接受的“消息”不同,做出不同的反应
重载(overload)----------------提供了函数调用的便利性
package a.b.c
class A{
public void a(){}
public void a(int i){}
}
覆盖(override):在派生类中定义函数,“替换”基类的函数
class A{
public void a()
}
class B{
public void a()
public static void main(String[] a){
A a=new A();
A b = new B();
a.a(); //无覆盖
b.a(); //被覆盖了---后绑定,程序运行的时候才知道到底指向的是A还是B,
//检查的时候检查的是A中是否有a(),但是实际运行的时候运行的是B中的a()
}
如果不想被覆盖 可以在前面加final,这样就不会在运行的时候进行动态的链接了,而是在编译的时候直接链接到final所在的函数
这样也会加快运行的速度------无需后绑定
静态函数也不可能是虚函数 static
但是不建议直接加static 因为静态函数推荐通过类名访问
注意:覆盖函数的访问权限不能比被覆盖函数的访问权限低 因为对操作的检查会出现问题,检查的时候是公有的,可以访问,但是实际运行的时候访问不了,为了避免这种问题,编译器会进行检查,这个属于语法错误,但是权限更大或者下相同是允许的。
覆盖函数抛出的检查异常不可以比被覆盖函数抛出的检查异常多