Java重载,覆盖,多态

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jpp_aaa/article/details/78728153

1、方法重载(Overload)必须满足以下条件:
●方法名相同
●方法的参数类型、个数、顺序(方法签名)至少有一项不相同
●方法的返回类型可以不相同
●方法的修饰符可以不相同
2、方法覆盖(Override)必须满足多种约束:
●子类方法的名称、参数签名和返回类型必须和父类的一致。
●子类方法不能缩小父类方法的访问权限
●子类方法抛出的异常必须和父类方法抛出的异常相同或是父类方法抛出的异常类的子类
●方法覆盖只存在于子类和父类(包括直接父类和间接父类)
●父类的静态方法不能被子类覆盖为非静态方法
●子类可以定义与父类的静态方法同名的静态方法,以便在子类中隐藏父类的静态方法。在编译时,子类定义的静态方法也必须满足与方法覆盖类似的约束:方法的参数签名一致,返回类型一致,不能缩小父类方法的访问权限,不能抛出更多的异常。
子类隐藏父类的静态方法和子类覆盖父类的实例方法的区别:运行时,java虚拟机把静态方法和所属的类绑定,而把实例方法和所属的实例绑定。

package hidestatic;

public class Base {
    // 实例方法
    void method() {
        System.out.println("method of Base");
    }

    // 静态方法
    static void staticMethod() {
        System.out.println("static method of Base");
    }
}

public class Sub extends Base {
    // 覆盖实例方法
    void method() {
        System.out.println("method of Sub");
    }

    // 隐藏父类的静态方法
    static void staticMethod() {
        System.out.println("static method of Sub");
    }

    public static void main(String[] args) {

        Base sub1 = new Sub();// sub1变量被声明为Base类型,引用Sub实例
        sub1.method();
        sub1.staticMethod();
        Sub sub2 = new Sub();
        sub2.method();
        sub2.staticMethod();
    }

}

输出结果:
method of Sub
static method of Base//父类的静态方法不能被子类覆盖
method of Sub
static method of Sub//父类的静态方法被子类隐藏

●父类非静态方法不能被子类覆盖为静态方法。
●父类的私有方法不能被子类覆盖

package privatetest;

public class Base {
private String showMe(){
    return "Base";
}
public void print(){
    System.out.println(showMe());
}
}
public class Sub extends Base {
    public String showMe() {
        return "Sub";
    }

    public static void main(String[] args) {
        // TODO 自动生成的方法存根
        Sub sub = new Sub();
        sub.print();
    }

}

输出结果:
Base

如果把Base的showMe()方法改成public类型的,输出结果会是Sub
●父类的抽象方法可以被子类通过两种途径覆盖:
①子类实现父类的抽象方法
②子类重新声明父类的抽象方法
public abstract class Base{
abstract void method1();
abstract void method2();
}
public abstract class Sub extends Base{
public void method1(){……}//实现method1方法,并扩大访问权限
public abstract void method2();//重新生命method2方法,仅仅扩大访问权限,但不实现

}
●父类的非抽象方法可以被覆盖为抽象方法
public class Base{
void method(){…}
}
public class Sub extends Base{
public abstract void method();
}
3、supe关键字

package usesuper;

public class Base {
    public String var = "Base's Variable";

    void method() {
        System.out.println("call Base's method");
    }
}
public class Sub extends Base {
    String var = "Sub's Variable";// 成员变量

    @Override
    void method() {
        System.out.println("call Sub's method");
    }

    void test() {
        String var = "Local Variable";
        System.out.println("var is " + var);// 局部变量var
        System.out.println("this.var is " + this.var);// 实例变量var
        System.out.println("super.var is " + super.var);// 父类的var
        method();
        this.method();
        super.method();
    }

    public static void main(String[] args) {
        // TODO 自动生成的方法存根
        Sub sub = new Sub();
        sub.test();

    }

}

输出结果:
var is Local Variable
this.var is Sub’s Variable
super.var is Base’s Variable
call Sub’s method
call Sub’s method
call Base’s method
4、多态
多态是指系统A访问系统B的服务时,系统B可以通过多种实现方式来提供服务,而这一切对系统A都是透明的。
如果把引用变量转换为子类类型,则称为向下转型。
如果把引用变量转换为父类类型,则称为向上转型。
参考https://www.cnblogs.com/chenssy/p/3372798.html
对于Java而言,它多态的实现机制遵循一个原则:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。
有关多态的经典例子:

package ABCD;


public class A {
    public String show(D obj) {
        return ("A and D");
    }

    public String show(A obj) {
        return ("A and A");
    }
}
public class B extends A {
    //重载
    public String show(B obj) {
        return ("B and B");
    }

    // 覆盖A方法的show
    public String show(A obj) {
        return ("B and A");
    }
}
public class C extends B{

}
public class D extends B{

}
public class Test {

    public static void main(String[] args) {
        // TODO 自动生成的方法存根
        A a1 = new A();
        A a2 = new B();
        B b = new B();
        C c = new C();
        D d = new D();
        System.out.println("1--" + a1.show(b));
        System.out.println("2--" + a1.show(c));
        System.out.println("3--" + a1.show(d));

        System.out.println("4--" + a2.show(b));
        System.out.println("5--" + a2.show(c));
        System.out.println("6--" + a2.show(d));

        System.out.println("7--" + b.show(b));
        System.out.println("8--" + b.show(c));
        System.out.println("9--" + b.show(d));

    }

}

输出结果:
1–A and A
2–A and A
3–A and D
4–B and A
5–B and A
6–A and D
7–B and B
8–B and B
9–A and D
其实在继承链中对象方法的调用存在一个优先级:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。

猜你喜欢

转载自blog.csdn.net/jpp_aaa/article/details/78728153
今日推荐