Java中不能被子类重写的父类结构举例(static、final、private、属性)

一、理论

  • Java中使用staticfinalprivate修饰的方法能被子类继承,但不会重写。此外,属性也能继承,但不能重写。
  • 属性和static修饰的方法。在子类中如果又定义了一份,那么从父类继承来的这些结构会被隐藏,存在2份。此时的属性包括普通属性、static修饰、final修饰、private修饰的。
  • final修饰的方法,重写会编译报错。
  • private修饰的方法,子类中可以定义和父类一样的私有方法。但是该私有方法不是重载,也不是重写,是子类新增的方法,就和子类扩展的一般方法一样。
  • 隐藏的结构采用静态绑定机制进行调用。
  • 在定义对象/变量时,等号左边的是编译类型,等号右边时运行类型。
  • 静态绑定机制:在编译期间就能确定调用子类还是父类的结构。等号左边的类型是父类就调用父类的结构,等号左边的类型是子类就调用子类类的结构。比如方法重载。
  • 动态绑定机制:在运行期间确定调用子类还是父类的结构。等号右边的类型是父类就调用父类的结构,等号右边的类型是子类就调用子类类的结构。比如方法重写。
  • 方法重载是一个类中多态性的体现,方法重写是父类和子类之间多态性的体现。

二、代码举例

static关键字修饰
import java.util.*;

/**
 * 静态方法和变量为静态绑定
 */

public class StaticInherit {
    public static void main(String[] args) {
        Collection<?>[] collections =
                {new HashSet<String>(), new ArrayList<String>(), new HashMap<String, String>().values()};
        System.out.println("静态绑定,看编译类型(左边)");

        System.out.println("----------> 通过对象调用方法 <--------------");
        System.out.println("左边为父类,调用父类");
        Super subToSuper = new Sub();
        for(Collection<?> collection: collections) {
            System.out.println(subToSuper.getType(collection));
        }

        System.out.println("-------------------------");
        System.out.println("左边为子类,调用子类");
        Sub sub = new Sub();
        for(Collection<?> collection: collections){
            System.out.println(sub.getType(collection));
        }

        System.out.println("----------> 通过类调用方法 <--------------");
        System.out.println("Super调用方法");
        for(Collection<?> collection: collections){
            System.out.println(Super.getType(collection));
        }
        System.out.println("---------------------");
        System.out.println("Sub调用方法");
        for(Collection<?> collection: collections){
            System.out.println(Sub.getType(collection));
        }

        System.out.println("------------> 通过对象调用属性 <-------------");
        System.out.println(subToSuper.name);
        System.out.println(sub.name);
        System.out.println("------------> 通过类调用属性 <-------------");
        System.out.println(Super.name);
        System.out.println(Sub.name);
    }

    abstract static class Super {
        static String name = "Super";

        public static String getType(Collection<?> collection) {
            return "Super:collection";
        }
        public static String getType(List<?> list) {
            return "Super:list";
        }
        public String getType(ArrayList<?> list) {
            return "Super:arrayList";
        }
        public static String getType(Set<?> set) {
            return "Super:set";
        }
        public String getType(HashSet<?> set) {
            return "Super:hashSet";
        }
    }

    static class Sub extends Super {
        static String name = "Sub";

        public static String getType(Collection<?> collection) {
            return "Sub"; }
    }
}
  • static修饰的结构,推荐使用类来调用,避免混淆。
属性
/**
 * 父类和子类同名属性不存在重写,父类的同名属性在子类中会被隐藏,在内存中存在2份;
 * 隐藏的结构会存在静态编译,所以同名属性的调用看等号左边的数据类型。
 */

public class IdenticalField {
    public static void main(String[] args) {
        Super subToSuper = new Sub();
        subToSuper.display();
        System.out.println("----------------");
        // 静态编译:看左边
        // Super
        System.out.println(subToSuper.name);
        Sub sub = new Sub();
        // Sub
        System.out.println(sub.name);
    }
}

class Super {
    String name = "Super";
    
    public void display(){}
}

class Sub extends Super {
    String name = "Sub";

    @Override
    public void display(){
        System.out.println(name);
        System.out.println(this.name);
        System.out.println(super.name);
    }
}

final关键字
public class FinalInherit {
    public static void main(String[] args) {
        SubF subF = new SubF();
        System.out.println(subF.name);

        SuperF subToSuper = new SubF();
        System.out.println(subToSuper.name);
    }

}

class SuperF {
    final String name = "SuperF";

    final void method(){
        System.out.println("final method SuperF");
    }
}

class SubF extends SuperF {
    final String name = "SubF";

    // 编译报错
    /*
    final void method(){
        System.out.println("final method SubF");
    }
     */
}
private关键字
public class PrivateInherit {
    public static void main(String[] args) {
        SubP sub = new SubP();
        System.out.println(sub.getName());
        sub.testMethod();

        System.out.println("-------------------------");
        SuperP subToSuper = new SubP();
        System.out.println(subToSuper.getName());
        subToSuper.testMethod();
    }
}

class SuperP {
    private String name = "SuperP";

    private void method(){
        System.out.println("private method SuperP");
    }

    public void testMethod(){
        method();
    }

    public String getName() {
        return name;
    }
}

class SubP extends SuperP{
    private String name = "SubP";

    private void method(){
        System.out.println("private method SubP");
    }

    @Override
    public void testMethod(){
        super.testMethod();
        // 等于this.method
        method();
    }

    @Override
    public String getName() {
        System.out.println(super.getName());
        //等于this.name
        return name;
    }
}
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值