类的继承以及this()调用和super()调用

本文深入解析Java中的继承机制,包括单继承特性、子类如何继承父类的非私有属性和方法,以及如何重写父类的public方法。同时,探讨了子类构造函数中super()和this()的使用规则及其在初始化过程中的作用。

继承

什么是继承?继承财产!儿子继承父亲的财产。

  • Java是单继承机制,即一个儿子类只能有一个父亲类。但是反过来,一个父亲类可以有很多个儿子。
class Dog{
	String name;
	void show() {
		System.out.println("汪汪");
	}
}
class Dog1{
        String name;
        void show(){
            System.out.println("汪汪");
        }
}
class son1 extends Dog{}//第一个儿子
class son2 extends Dog{}//第二个儿子
class son3 extends Dog1,Dog{}//错误
class son4 extends Dog1 extends Dog{}//错误
  • 子类继承到父类的非私有属性,非私有方法。私有的儿子类是拿不到的。
class Dog{
	String name;
	private void show() {
		System.out.println("父类私有你拿不到");
	}
	void show1() {
		System.out.println("不是私有可以拿得到");
	}
}
class son extends Dog{}
  • 子类继承父类可以重写父类的public方法,这样创建的子类对象,调用与父类同名方法时优先调用的是子类方法。
class Dog{
	String name;
	 void show() {
		System.out.println("父类show");
	}
}
class son extends Dog{
	void show(){
		System.out.println("子类show");
	}
}
public class Test{
	public static void main(String[] args) {
		son s = new son();
		s.show();//调用的是子类的show(),可简单理解为就近原则
	}
}
  •  子类继承父类调用父类的protected方法,但是不可以重写父类的protected方法,编译会报错。
class Fu{
    protected void show(){
        System.out.println("子类可以重写父类的protected方法吗");
    }
}
class Zi extends Fu{
    void show(){//这里会报错,编译不通过
        System.out.println("不可以哦,会报错");
    }
}

这里可以简单的理解为就近原则,子类重写父类方法。其本质是涉及对象空间对象调用方法的问题。

对象创建之后存在于堆中,对象调用方法时会现在对象空间寻找show方法,没找到才会往父类空间找。

  • 鉴于构造函数的重要性,继承父类时,子类在调用自己构造函数之前会自动通过super()去调用父类的构造函数完成父类属性的初始化。super. 则调用父类的属性或者方法。
class Dog{
        String name = "汪汪";
	Dog(){
	System.out.println("父类构造");
	}
}
class son extends Dog{
	son(){
        //此处隐藏了一个:super();
	System.out.println("子类构造");
        System.out.println(super.name);//通过super.去调用父类属性,也可以是方法,但不包括构造方法。
	}
}
public class Test{
	public static void main(String[] args) {
	son s = new son();
         //先输出的是父类构造,后出来的是子类构造
	}
}

也就是说,在调用子类构造函数的时候,子类中的构造函数会自动调用一个super()去调用父类的构造函数,先完成父类的属性初始化,这是因为子类很有可能需要用到父类的一些属性,所以调用父类构造为子类准备资源。

class Dog{
	Dog(){
		System.out.println("父类构造");
	}
}
class son extends Dog{
	son(){
	this();//报错,有this()则不会有super(),而没有super()则无法调用父类构造函数
	System.out.println("子类构造");
	}

}

 

class son extends Dog{
	son(){
	System.out.println("子类构造");
        super();//报错,super()未声明则默认放在第一句,声明了则必须放在第一句
	}

}
class son extends Dog{
	son(){
		super();//正确,子类中可以有多个super()
		System.out.println("子类构造");
	}
	son(String name){
		super();
	}
}

那super()究竟是什么?

拿Dog类来说,super()就可以看作是Dog();  自然super("参数")就可以看成是 Dog("参数");    (同理其实this()也一样)

class Dog{
	Dog(String name){
		System.out.println("父类构造");
	}
}
class son extends Dog{
	son(){
		super();//报错,这里相当于调用Dog(),但是父类的构造函数是Dog(String name);
                        //是有String类的参数的,所以调用错误!
		System.out.println("子类构造");
	}
}

这里可以对super()做一个总结:

  1. super()存在于继承中,具体存在于子类构造函数中。
  2. 可以自己给出,如不给出则系统默认给出。
  3. super() 等同于  父类名() 
  4. super()可有参可无参,具体需要看父类,若是父类构造函数只有有参构造,则必须自己添加super(有参),父类有无参则可不添加super(),系统会自动给出。
  5. super()为的就是调用父类构造初始化,为子类可能要用到父类的属性提供初始化,即提供资源。
  6. super()默认在子类构造函数的第一句,不能放在其他位置,同样,不能与this()出现在同一个构造函数中,因为它们都放在第一句。
  7. super()至少有一个,有多个构造函数,自己可添加多个,否则系统默认一个,但默认的super()是调用父类的无参构造,必须满足上面的4.
  8. super. 则可以调用父类的属性或方法。

this()调用:

  • this指的是当前类,通过   this.  可调用当前类的  属性,方法。
  • 而this()是调用当前类的无参构造,同样this(参数)调用的是当前类的有参构造,也只存在于构造函数中。
  • 并且也只能出现在构造函数的第一句。
  • 这样的话就可以在构造函数中通过this()调用其他的构造函数,但是要注意,构造函数调用构造函数的时候,不能形成回调,也就是形成一个环形调用,这样会形成递归调用,导致栈溢出。
class son extends Dog{
	int age = 19;
	son(){
		this("参数");//调用son(String name)这个有参构造。将“参数”传递给了son的有参构造的 name
		System.out.println(this.age);//通过  this. 调用当前类属性
		this.show();//通过 this. 来调用当前类方法
	}
	son(String name){
                System.out.println(super.name);//通过super. 调用父类属性,也可以调用父类方法,但不包括构造方法。
		System.out.println(name);//输出  参数
	}
	void show() {
		System.out.println("通过this来调用我啊");
		
	}
}

总结: 

  1. 无论是this()调用还是super()调用,都是封装好的一种机制,都能减少代码冗余,增强代码封装性
  2. this()和super()有很多相似之处,this()侧重当前类的构造方法调用,super()是对父类构造方法的调用
  3. this.  是对当前类,也就是子类的属性方法的调用,super. 是对父类属性方法的调用。
  4. this()和super()都只能放在构造函数内的第一句,this()可以有多个(子类中) ,super()至少有一个,也可以有多个。
  5. this()  super() 可以其实就相当于  类名()  
  6. 万变不离其综,不变其魂。

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值