一. 属性
1. 子类和父类重名的属性不会冲突,他们存在两个域之中,但是其类型需要一致。
规则:引用是谁就调用谁的属性。
//父类
class Father{
public static String svalue = "fa_static";
public String value = "fa";
}
//子类
class Son extends Father{
public static String svalue = "son_static";
public String value = "son";
}
class Test{
public static void main(String[] args) {
Father obj = new Father();
obj.svalue; // "fa_static"
obj.value; // "fa"
//重新赋值
obj = new Son();
obj.svalue; // "fa_static"
obj.value; // "fa"
Son son = new Son();
son.svalue; // "son_static"
son.value; // "son"
}
}
2. 父类中独有的属性,被子类和父类共同指向。因此子类可以操作父类的属性。
//父类
class Father{
public static String svalue = "fa_static";
public String value = "fa";
}
//子类
class Son extends Father{
{
svalue = "son_static";
value = "son";
}
}
class Test{
public static void main(String[] args) {
Father obj = new Father();
obj.svalue; // "fa_static"
obj.value; // "fa"
//重新赋值
obj = new Son();
obj.svalue; // "son_static"
obj.value; // "son"
//
obj = (Father) obj;
obj.svalue; // "son_static"
obj.value; // "son"
Father.svalue; // "son_static"
}
}
二. 重写方法
1. static方法不能被重写。重名static方法存在两个域中,但是其返回值要和父类static方法返回值一样或是返回值的子类,且权限修饰符的作用范围要大于等于(public > protected > defalt > private)
规则:引用是谁就调用谁的static方法。
//父类
class Father{
public static void get(){
System.out.println("father");
}
}
//子类
class Son extends Father{
public static void get() {
System.out.println("son");
}
}
class Test{
public static void main(String[] args) {
Father obj = new Father();
obj.get(); // "father"
obj = new Son();
obj.get(); // "son"
}
}
2. 非static方法可以被重写,其返回值要和父类方法返回值一样或是返回值的子类,且权限修饰符的作用范围要大于等于(public > protected > defalt > private),抛出的异常要和父类方法抛出的异常一样或是异常的子类。
--0. 有一个A类,有一个B类(继承A类)。我们想让子类可以代替父类出现在任何父类出现的地方,假如父类有一个方法返回A类对象,程序中有一处用到了这个方法。
--1. 返回值问题:如果子类方法和父类方法返回值相同或者是其子类(如:B类),就可以在程序中代替(多态)父类(因为B类可以自动向上转型成为A类)
--2. 权限修饰符问题:如果子类方法的权限收紧,子类代替(多态)父类时程序不一定能够使用子类方法,从而出现报错。
--3. 异常问题:如果子类方法抛出的异常不是父类方法的异常及其子类,子类代替(多态)父类时程序写好的try...catch就不能捕获子类的异常了,从而出现错误。
3. 多态时调用什么方法看的是引用,具体实现看的是多态的对象。
class A{
public void getA(A a){
System.out.println("A...A");
}
}
class B extends A{
public void getA(A a){
System.out.println("B...A");
}
public void getA(B b){
System.out.println("B...B");
}
}
class C extends B{ }
class Test{
public static void main(String[] args) {
A a = new B();
// a.getA方法传入C对象时,找到了A类的getA(A a)方法,然后jvm发现子类重写了这个方法,所以就去执行B类的getA(A a)方法。
a.getA(new C()); // "B...A"
}
}