美文网首页Java
Java编程思想 继承

Java编程思想 继承

作者: 静享时光 | 来源:发表于2020-05-08 23:14 被阅读0次

    这里不会介绍继承的基本概念和用法。这篇文章介绍继承中需要注意的几个点,并且文中也不会进行详细的理论说明,因为直接用示例,通过示例的结果进行总结分析,更清楚明了。

    子类和父类的成员变量和构造方法的加载顺序

    如果一个类继承了另一个类,在加载子类的构造方法时,会层次向上先加载父类的的构造。
    另外需要注意的是,加载一个类的时候,类的成员变量会先于构造方法加载

    class A {
        private String s;
    
        A(String s) {
            this.s = s;
            PrintUtils.print("Creating  A: " + s);
        }
    
        protected void dispose() {
            PrintUtils.print("disposing A: " + s);
        }
    }
    
    class B {
        private String s;
    
        B(String s) {
            this.s = s;
            PrintUtils.print("Creating  B: " + s);
        }
    
        protected void dispose() {
            PrintUtils.print("disposing B: " + s);
        }
    }
    
    
    class C {
        private A a = new A("C-A");
        private B b = new B("C-B");
    
        C() {
            PrintUtils.print("Creating  C");
        }
    
        protected void dispose() {
            PrintUtils.print("disposing C ");
            a.dispose();
            b.dispose();
        }
    }
    
    class D extends C {
        private A a = new A("D-A");
        private B b = new B("D-B");
    
        D() {
            PrintUtils.print("Creating  D");
        }
    
        protected void dispose() {
            PrintUtils.print("disposing D ");
            a.dispose();
            b.dispose();
            super.dispose();
        }
    }
    
    class E extends D {
        private A a = new A("E-A");
        private B b = new B("E-B");
    
        E() {
            PrintUtils.print("Creating  E" + "  a是否为空: " + (a == null) + " B是否为空: " + (b == null));
        }
    
        protected void dispose() {
            PrintUtils.print("disposing E ");
            a.dispose();
            b.dispose();
            super.dispose();
        }
    }
    
    public class PracticeDemo4 extends E {
        private A a = new A("PracticeDemo4-A");
        private B b = new B("PracticeDemo4-B");
    
        public PracticeDemo4() {
            PrintUtils.print("Creating  PracticeDemo4");
        }
    
        protected void dispose() {
            PrintUtils.print("disposing PracticeDemo4 ");
            a.dispose();
            b.dispose();
            super.dispose();
        }
    
        public static void main(String[] args) {
            PracticeDemo4 demo4 = new PracticeDemo4();
            PrintUtils.print("Bye!");
            demo4.dispose();
        }
    
        /**
         *
         *输出结果:
         Creating  A: C-A
         Creating  B: C-B
         Creating  C
         Creating  A: D-A
         Creating  B: D-B
         Creating  D
         Creating  A: E-A
         Creating  B: E-B
         Creating  E  a是否为空: false B是否为空: false
         Creating  A: PracticeDemo4-A
         Creating  B: PracticeDemo4-B
         Creating  PracticeDemo4
         Bye!
         disposing PracticeDemo4
         disposing A: PracticeDemo4-A
         disposing B: PracticeDemo4-B
         disposing E
         disposing A: E-A
         disposing B: E-B
         disposing D
         disposing A: D-A
         disposing B: D-B
         disposing C
         disposing A: C-A
         disposing B: C-B
         *
         */
    
    总结:

    由打印结果会发现,先层层向上初始化父类的成员变量,父类的成员变量加载结束之后,加载父类的构造函数,最后才加载子类的成员变量和构造方法。

    构造器内部的多态行为

    class Parent4 {
        public Parent4() {
            PrintUtils.print("Parent4 before");
            draw();
            PrintUtils.print("Parent4  after");
        }
    
        public void draw() {
            PrintUtils.print("Parent4 draw");
        }
    }
    
    class Child4 extends Parent4 {
    
        private int data;
    
        public Child4(int r) {
            data = r;
            PrintUtils.print("Child4  data: " + data);
        }
    
        public void draw() {
            PrintUtils.print("Child4 draw  data: " + data);
        }
    }
    
    
    public class PracticeTest5 {
    
        public static void main(String[] args) {
            new Child4(6);
            PrintUtils.print("//////////////////////////");
            new Child4(5);
            PrintUtils.print("//////////////////////////");
            new Child4(4);
            PrintUtils.print("//////////////////////////");
            new Child4(3);
            PrintUtils.print("//////////////////////////");
            new Child4(2);
            PrintUtils.print("//////////////////////////");
            new Child4(1);
            PrintUtils.print("//////////////////////////");
    
    
            /**
             * 打印结果
             *
             * Parent4 before
             * Child4 draw  data: 0
             * Parent4  after
             * Child4  data: 6
             * //////////////////////////
             * Parent4 before
             * Child4 draw  data: 0
             * Parent4  after
             * Child4  data: 5
             * //////////////////////////
             * Parent4 before
             * Child4 draw  data: 0
             * Parent4  after
             * Child4  data: 4
             * //////////////////////////
             * Parent4 before
             * Child4 draw  data: 0
             * Parent4  after
             * Child4  data: 3
             * //////////////////////////
             * Parent4 before
             * Child4 draw  data: 0
             * Parent4  after
             * Child4  data: 2
             * //////////////////////////
             * Parent4 before
             * Child4 draw  data: 0
             * Parent4  after
             * Child4  data: 1
             * //////////////////////////
             *
             *
             */
        }
    }
    
    总结:

    由结果可以看到,在创建子类的时候,执行了父类的构造方法。在父类中触发调用draw方法,由于被覆写了,所以调用的是子类的draw方法,但是此时子类的成员变量data还没有初始化,所以还是默认的初始值0,而不是我们设置的值。直到子类的初始化完成,在子类的构造中打印的结果data才是我们设置的值。

    相关文章

      网友评论

        本文标题:Java编程思想 继承

        本文链接:https://www.haomeiwen.com/subject/lxscnhtx.html