问题列表:
1. Java中子类中可以有与父类相同的属性名吗?
2. Java中子类继承了父类的私有属性及方法吗?
3. Java中抽象类到底能不能被实例化?
1. Java中子类中可以有与父类相同的属性名吗?
JAVA里,子类里的属性名与父类的一个属性名一样,那么就说子类的这个属性把父类的这个属性隐藏了。子类的实例访问的是自己的,父类是不受影响的。 子类如果想访问父类的同名属性要加super
2. Java中子类继承了父类的私有属性及方法吗?
子类继承父类,子类拥有父类所有的属性和方法,于是使用程序去验证,发现父类的私有属性和私有方法,子类是不能访问的,当然一些父类的私有属性可能可以通过相应的方法访问到,但是私有的方法似乎不能简单的访问(这里暂不考虑Java反射机制)于是我简单的认为,子类不能继承父类私有的属性及方法,但是分析了内存后,我发现我是错的,在一个子类被创建的时候,首先会在内存中创建一个父类对象,然后在父类对象外部放上子类独有的属性,两者合起来形成一个子类的对象。所以所谓的继承使子类拥有父类所有的属性和方法其实可以这样理解:子类对象确实拥有父类对象中所有的属性和方法,但是父类对象中的私有属性和方法,子类是无法访问到的,只是拥有,但不能使用。就像有些东西你可能拥有,但是你并不能使用。所以子类对象是绝对大于父类对象的,所谓的子类对象只能继承父类非私有的属性及方法的说法是错误的。可以继承,只是无法访问到而已。
3. Java中抽象类到底能不能被实例化?
在学习的过程中,发现了一个问题,抽象类在没有实现所有的抽象方法前是不可以通过new来构建该对象的,但是抽象方法却是可以有自己的构造方法的。这样就把我搞糊涂了,既然有构造方法,又不可以通过new来创建,那么抽象类在没变成具体类的时候究竟可不可以实例化呢?
抽象类其实是可以实例化的,但是他的实例化方式不是通过new方式来创建对象,而是通过父类的引用来指向子类的实例来间接地实现父类的实例化(因为子类要实例化前,一定会先实例化他的父类。这样创建了继承抽象类的子类的对象,也就把其父类(抽象类)给实例化了).但是:接口是不能被实例化的(接口压根就没有构造函数)
在java中所有类的父类都是Object。在所有类进行初始化的时候都会调用Object的初始化方法,注意初始化方法并不是构造方法,初始化完成后就在内存中存在(这个过程就是类加载过程)。抽象类也一样有初始化方法。只不过我们在进行类实例化的时候比如通过 new 关键字产生实例,java语言不允许抽象类有实例产生,所以抽象类不能被实例化。
在上面说的初始化这些内容,一定要分清楚 类的初始化 与 对象的实例化,实例化和初始化需要分辨开来,父类初始化并不是又创建一个父类的对象,而是把父类中定义的对象相关的属性都初始化,因为这些属性子类对象也是拥有的。所以为了保证子类对象的完整性,要从最底层的父类开始,逐级初始化,所有初始化都完成后才会生成一个完整的子类对象。
以上如果还有不明白的同学,那么就记住一句话:虚拟机能干的事,你不能干;代码中不能显式实例化抽象类。这是java的规定,你不得不遵守
这里还是举个例子吧,要不然空话套不住狼啊:
1 abstract class Father { 2 private String str; 3 4 public Father(String a) { 5 System.out.println("父类已经实例化"); 6 this.str=a; 7 System.out.println(str); 8 } 9 10 public abstract void play(); 11 } 12 13 public class child extends Father { 14 15 public Child(String a) { 16 super(a); 17 System.out.println("子类已经实例化"); 18 } 19 20 @Override 21 public void play() { 22 System.out.println("我实现了父类的方法"); 23 } 24 25 public static void main(String[] args) { 26 Father aa = new Child("abc"); 27 } 28 }
运行结果如下:
父类已经实例化 abc 子类已经实例化
课外补充:
Calendar中的getInstance()
Calendar是抽象类不能直接通过new对象,但是提供的静态getInstance()就是给Calendar创建对象。
从Calendar.getInstance() 中所获得的实例其实就是一个 "GreogrianCalendar" 对象
GreogrianCalendar就是Calendar的子类,他实现了Calendar里面的抽象方法。过父类的引用来指向子类的实例来间接地实现父类的实例化。同时,使用getInstance()有诸多好处:
1。 new 一定要生成一个新对象,分配内存;getInstance()则不一定要再次创建,它可以把一个已存在的引用给你使用,这在效能上优于new;
2。new创建后只能当次使用,而getInstance()可以跨栈区域使用,或者远程跨区域使用。所以getInstance()通常是创建static静态实例方法的。
这个是在学习和生活中遇到的一些最基础的且自己感觉模棱两可的java基础,实时的会补充进来,即持续更新中。