class Father{
Father(){
System.out.println("fatherrun!");
}
}
class Son extends Father{
Son(){
System.out.println("sonrun!");
}
}
public class Demo {
public static void main(String[] args) {
new Son();
//father run!
//son run!
}
}
在子类构造对象时,访问子类构造函数时,父类也运行。为什么哪?
在子类构造函数中第一行有一个默认的隐式语句:super();并且子类实例化过程中,子类所有的构造函数默认都会访问父类中的空参数的构造函数,如果父类中没有定义空参的构造函数,那么子类构造函数必须用super显式调用父类中的哪个构造函数。
Son(){
super(4);
System.out.println("sonrun!");
}
为什么子类实例化过程中要调用父类的构造函数?
class Father{
int num;
Father(){
num=10;
}
}
public class Son extends Father{
Son(){
System.out.println(num);
}
public static void main(String[] args) {
new Son();//10
}
}
那是因为子类继承了父类,获取到了父类中的内容(属性),所以在使用父类内容之前,要先看父类是如何对自己的内容进行初始化的。Super语句要定义在子类构造函数的第一行,因为父类的初始化动作要先完成。
如果子类构造函数中如果使用this调用了本类构造函数时,那么子类的此构造函数中的super就没有了,因为super和this都只能定义第一行。所以只能有一个,保是可以保证的是,子类中肯定会有其它的构造函数访问父类的构造函数。
class Father{
int num;
Father(){
}
}
public class Son extends Father{
Son(){//这个调用父类构造函数
}
Son(int num){
this();//此时有this情形
}
public static void main(String[] args) {
new Son(20);//20
}
}
class Father{
int num=10;
Father(){
show();
}
public void show(){
System.out.println("Father run"+num);
}
}
public class Son extends Father{
int num=20;
Son(){
show();
}
public void show(){
System.out.println("son run"+num);
}
public static void main(String[] args) {
new Son();
}
}
//son run 0
//son run 20
一个对象实例化过程Person p=new Person():
1. JV M会读取指定路径下Person.class文件,并加载进内存,并会先加载Person的父类(如果有直接父类);
2. 在堆内存中为此对象开辟空间,分配地址。
3. 并在对象空间中,对对象中的属性进行默认初始化。
4. 调用对应的构造函数进行初始化。
5. 在构造函数中,第一行会先调用父类的构造函数进行初始化
6. 父类初始化完毕,再对子类的属性进行显式初始化
7. 再进行子类构造函数的特定初始化
8. 初始化完毕,将地址值赋给引用变量
//内部类访问特点:1.内部类可以直接访问外部类中的成员。
//2.外部类要访问内部类,必须建立内部类的对象。
class Outer{
private int num=3;
class Inner{
void show(){
System.out.println("innerrun!"+num);//访问外部类
}
}
public void fun(){
Inner inner=new Inner();//访问内部类
inner.show();
}
}
public class Son{
public static void main(String[] args) {
Outer.Inner in=new Outer().new Inner();//外部类以外的类访问内部类成员
in.show();
}
}
//2.如果内部类是static的相当于一个外部类
class Outer{
static private int num=3;//此处有变化
static class Inner{
static void show(){
System.out.println("innerrun!"+num);//访问外部类
}
}
}
public class Son{
public static void main(String[] args) {
Outer.Inner in=new Outer.Inner();//外部类以外的类访问内部类成员
Outer.Inner.show();//通过类直接访问类成员
}
}