zoukankan      html  css  js  c++  java
  • java的继承

    我总是记不住继承是怎么个机制,今天我来彻底的总结一下。

     感谢海子,给出他的链接http://www.cnblogs.com/dolphin0520/p/3803432.html

    先了解一下初始化的顺序

    当程序执行时,需要生成某个类的对象,java执行引擎会先检查是否加载了这个类,如果没有加载,则先执行类的加载再生成对象,如果已经加载,则直接生成对象。

    类加载的过程中,类的static成员变量会被初始化,类的static语句块会被执行。

    java中类是按需加载,只有当用到这个类的时候才会加载这个类,并且只会加载一次

    看看这个例子

    public class T{
        public static void main(String[] args){
            Shape shape1 = new Shape();
            Shape shape2 = new Shape();
        }
    }
    
    class Shape{
        
        static{
            System.out.println("static is cout");
        }
        
        public Shape(){
            System.out.println("shape is cout");
        }
    
    }

    会输出什么?

    static is cout
    shape is cout
    shape is cout
    View Code

    解释:在类加载时会执行static块,而且只执行一次。创建了两个Shape实例,所以shape的构造器被调用两次

    再来看看

    在生成对象的过程中,会先初始化对象的成员变量,然后再执行构造器。

    public class T{
        public static void main(String[] args){
            new Circle();
        }
    }
    
    class Shape{
        
        public Shape(){
            System.out.println("shape is cout");
        }
     
    }
    
    class Circle{
            
        public Circle(){
            System.out.println("circle is cout");
        }
        
        Shape shape=new Shape();
    }

    结果:

    shape is cout
    circle is cout
    View Code

    上面标记的字体已经解释清楚了,这里并没有用继承,想想circle继承shape会有什么不一样呢。

    (偷偷的告诉你,会输出 shape is cout  shape is cout   circle is cout ;因为构造circle前先构造Shape,输出第一句。然后初始化shape对象,调用Shape,输出第二句话。然后调用Circle的构造函数)

    为了看是否真的清楚了,我出一个题目

    public class T{
        public static void main(String[] args){
            new Circle();
        }
    }
    class Rudio{
        public Rudio(String type){
            System.out.println(type+" Rudio is cout");
        }
    }
    
    class Shape{
        
        private Rudio r=new Rudio("shape");
        
        public Shape(){
            System.out.println("shape is cout");
        }
    
    }
    
    class Circle extends Shape{
        
        
        public Circle(){
            System.out.println("circle is cout");
        }
        
        private Rudio r=new Rudio("circle");
    }
    shape Rudio is cout
    shape is cout
    circle Rudio is cout
    circle is cout
    View Code

    如果不能看懂,说明还要琢磨琢磨

    再来看看下面这个例子

    public class Test{
        public static void main(String[] args){
            Shape shape=new Circle();
            System.out.println(shape.name);
            System.out.println(shape.age);
            shape.printType();
            shape.printName();
        }
    }
    
    class Shape{
        public String name="shape";
        public static int age=10;
        
        public Shape(){
            System.out.println("shape 的构造器");
        }
        
        public void printType(){
            System.out.println("this type shape");
        }
        
        public static void printName(){
            System.out.println("this name shape");
        }
    }
    
    class Circle extends Shape{
        public String name="Circle";
        public static int age=18;
        
        public Circle(){
            System.out.println("Circle 的构造器");
        }
        
        public void printType(){
            System.out.println("this type Circle");
        }
        
        public static void printName(){
            System.out.println("this name Circle");
        }
    }

    想想结果是什么?

    shape的构造器
    Circle的构造器
    shape
    10
    this type Circle
    this name shape
    View Code

     解释一下:

     创建了一个父类类型的子类实例,因此,shape中的变量是Shape中的变量。如果子类覆盖了父类的方法,调用子类的方法。如果父类某个方法加了static,final关键字,那么父类的该方法对子类隐藏,即使子类有同名方法,那依然是子类自己的方法,与父类无关。

    先调用shape的构造器和Circle的构造器没什么疑问,然后输出shape和10,告诉我们shape的成员是从Shape获得。由于子类覆盖了父类的printType方法,因此调用该方法输出的是this type Circle。由于printName方法使用了static变量,对子类隐藏了,所以输出this name shape

    其实这总结出来三句话

    1、父类的构造器调用以及初始化过程一定在子类的前面

    2、类中的变量会在任何方法调用之前得到初始化

    3、子类覆盖父类,会调用子类的方法;父类成员和方法如果是static,final的会隐藏子类的同名成员和方法

    再来看看这个

    public class T{
        public static void main(String[] args){
            Circle circle=new Circle();
            System.out.println(circle.name);
            System.out.println(circle.age);
            circle.printType();
            circle.printName();
        }
    }
    
    class Shape{
        public String name="shape";
        public static int age=10;
        
        public Shape(){
            System.out.println("shape 的构造器");
        }
        
        public void printType(){
            System.out.println("this type shape");
        }
        
        public static void printName(){
            System.out.println("this name shape");
        }
    }
    
    class Circle extends Shape{
        public String name="Circle";
        public static int age=18;
        
        public Circle(){
            System.out.println("Circle 的构造器");
        }
        
        public void printType(){
            System.out.println("this type Circle");
        }
        
        public static void printName(){
            System.out.println("this name Circle");
        }
    }

    想想运行结果

    shape的构造器
    Circle的构造器
    Circle
    18
    this type Circle
    this name Circle
    View Code

     这是故意让你们明白究竟是怎么构造的

    最后再总结一下

    1、创建子类时会先创建父类

    2、创建类时,最先是给类中成员变量初始化,然后才是调用构造函数

    3、父类中加了static和final的方法会对子类隐藏。父类和子类同名的方法会被覆盖,被隐藏了的方法除外。

  • 相关阅读:
    第四次作业
    随机点名
    表单验证
    冒泡排序&&选择排序
    Equals相等
    String类
    最终类final
    Eclipse的设置
    Equals相等(测试)
    猜数字
  • 原文地址:https://www.cnblogs.com/wabi87547568/p/5322469.html
Copyright © 2011-2022 走看看