贼经典—关于面向对象

来源:互联网 发布:九十年代的事件知乎 编辑:程序博客网 时间:2024/06/05 06:18
public class Base{    private String baseName = "base";    public Base()//构造方法    {        callName();    }    public void callName()//对象方法    {        System. out. println(baseName);    }    static class Sub extends Base//静态内部类    {        private String baseName = "sub";        public void callName()//对父类方法的重写        {            System. out. println (baseName) ;        }    }    public static void main(String[] args)    {        Base b = new Sub();    }}
------程序输出为null
附:http://www.open-open.com/lib/view/open1482802441249.html
    http://www.cnblogs.com/pbting/p/4858912.html#3550571
一、在 JAVA 程序中类可以被明确或者隐含地实例化有四种途径:
(1)明确使用 new 操作符;
(2)调用 Class 或者 Constructor 对象的 newInstance() 方法;
(3)调用任何现有对象的 clone() 方法;
(4)或者通过 objectInputStream 类的 getObject() 方法反序列化。
二:继承
Java保证了一个对象被初始化前其父类也必须被初始化。有下面机制来保证:
Java强制要求任何类的构造函数中的第一句必须是调用父类构造函数或者是类中定义的其他构造函数。
如果没有构造函数,系统添加默认的无参构造函数。
如果我们的构造函数中没有显示的调用父类的构造函数,那么编译器自动生成一个父类的无参构造函数
三:多态
父类中的构造函数调用了 callName 方法,在题目中是通过 new Sub() 调用子类的 callName 方法。
四:
构造器的初始化顺序大概是:
父类静态块 ->子类静态块 ->父类初始化语句 ->父类构造函器 ->子类初始化语句 子类构造器。
主要的过程:
1、从new Sub()开始,子类构造函数本质为
public Sub(){
super();
baseName = "sub";
}
2、super()为父类构造函数,父类构造函数本质为
public Base(){
baseName = “base”;//注意:java没有字段的重写,所以此处的baseName和子类的baseName是两回事
callName();//此处子类重写了该方法,调用子类重写后的
}
3、但调用子类的callName()方法时,没有为子类的base Name字段赋初值,及以上都是调用super()时发生的,而给子类
的baseName赋值发生在super()方法之后,所以执行子类的callName()方法时,输出为null
穿插一个概念:static{...}是静态代码块(用于类的属性初始化),在方法或语句中的{...}是普通代码块(执行次序,按先后顺序执行),
在类中的{...}是构造代码块(执行次序优先于构造函数)
静态块在一个程序里只执行一次,构造代码块创建一个对象都会执行一次
静态代码块>main方法>构造代码块>构造函数
附:http://www.cnblogs.com/sophine/p/3531282.html

                                             
0 0