ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

【Java之旅】9.继承 Part Ⅱ

2021-01-28 21:34:40  阅读:62  来源: 互联网

标签:Java String 之旅 子类 --- Part 父类 super public


【Java之旅】9.继承 Part Ⅱ

9.1引子

​ 一个孩子一定得有个父亲,有其子必有其父。

当我们创建子类的时候,也应该会创建他的父类。

我们来写个代码验证一下我们的想法。

public class Inheritance
{
	public static void main(String[] args) 
	{
		Dog mo = new Dog();
		Dog kupurk = new Dog("kupurk","二哈");
		System.out.println(mo);
		System.out.println(kupurk);
	}
}

class Animal
{
	private String name;
	private String type;
	public Animal()
	{
		System.out.println("---父类无参构造执行---");
	}
	public Animal(String name,String type)
	{
		this.name = name;
		this.type = type;
		System.out.println("---父类的有参构造执行---");
	}
	public String toString()
	{
		return "["+ name + "," + type + "]";
	}
}
class Dog extends Animal
{
	public Dog()
	{
		System.out.println("---子类无参构造方法执行---");
	}
	public Dog(String name,String type)
	{
		/*
		this.name=name;
		this.type=type;
		*/
		System.out.println("---子类有参构造方法执行---");
	}
}

输出结果:

---父类无参构造执行---    -----1
---子类无参构造方法执行---  -----2
---父类无参构造执行---  -----3
---子类有参构造方法执行---  -----4
[null,null]   -----5
[null,null]   -----6

从上面输出的语句我们可以看出,每当我们构造一个子类对象的时候

总是会先构造一个父类对象。

所以我们可以认为,在子类的构造方法中,隐藏着一个父类的构造器,并且这个构造方法在子类构造方法中第一个实行

并且我们由3、4发现,不论我们使用有参或者无参的子类构造器去new子类对象,隐藏的父类构造器 总是是无参的

所以,通过以上结论,我们可以推断出 子类构造方法中的原始面貌应该如下:

public Dog()
{
    //隐藏的父类函数构造器 Animal();
    System.out.println("---子类无参构造方法执行---");
}

9.2 Super()

还是上面的代码,不过我们在子类构造器中偷偷加了一句super()

public class Inheritance
{
	public static void main(String[] args) 
	{
		Dog mo = new Dog();
		Dog kupurk = new Dog("kupurk","二哈");
		System.out.println(mo);
		System.out.println(kupurk);
	}
}

class Animal
{
	private String name;
	private String type;
	public Animal()
	{
		System.out.println("---父类无参构造执行---");
	}
	public Animal(String name,String type)
	{
		this.name = name;
		this.type = type;
		System.out.println("---父类的有参构造执行---");
	}
	public String toString()
	{
		return "["+ name + "," + type + "]";
	}
}
class Dog extends Animal
{
	public Dog()
	{
        super();
		System.out.println("---子类无参构造方法执行---");
	}
	public Dog(String name,String type)
	{
		super();
		System.out.println("---子类有参构造方法执行---");
	}
}

输出结果:

—父类无参构造执行—
—子类无参构造方法执行—
—父类无参构造执行—
—子类有参构造方法执行—
[null,null]
[null,null]

加了super()的构造器和没加super()的构造器输出是一样的。

我们发现我们明明对子类是有参构造,但是输出来的确实两个初值null

那我们如何才能用有参构造给Dog类的对象赋值??

我们要让两个String型变量输入父类让他们赋值

class Dog extends Animal
{
	public Dog()
	{
        super();
		System.out.println("---子类无参构造方法执行---");
	}
	public Dog(String name,String type)
	{
		super(name,type);
		System.out.println("---子类有参构造方法执行---");
	}
}

输出结果

---父类无参构造执行---
---子类无参构造方法执行---
---父类有参构造执行---
---子类有参构造方法执行---
[null,null]
[kupurk,二哈]

成功给对象kupurk赋值,而且我们可以注意到第三句变成了父类有参构造而不是无参构造。

那我们再来看看如果把super()不放在第一句会怎么样

class Dog extends Animal
{
	public Dog()
	{
		System.out.println("---子类无参构造方法执行---");
		super();
	}
	public Dog(String name,String type)
	{
		System.out.println("---子类有参构造方法执行---");
		super();
	}
}

输出结果:

Inheritance.java:36: 错误: 对super的调用必须是构造器中的第一个语句
                super();
                     ^
Inheritance.java:41: 错误: 对super的调用必须是构造器中的第一个语句
                super();
                     ^
2 个错误

super()的调用必须是构造器中的第一个语句

所以我们可以发现那个隐藏在子类构造器中的父类无参构造不是Animal(), 而是 super().

super()可以省略也可以不省略

② 矛盾

​ 我在上一篇博客中说过,子类无法构造父类,因为子类没有继承得到父类的构造器,那super()还能是子类中父类的构造器吗?

这就说不通了。

​ 所以 super()不是父类的构造,而是通过super关键字构造了父类的特征

③super()用法

  • 在构造方法中只能出现一次,且是第一条语句。
  • 只能用于构造方法。

9.3 super关键字

这里要注意是super关键字,而不是super().

super有上级的意思,super所代表的是父类的特征,这些特征归子类所有

父类的特征:属性、方法、类名

super可以在成员方法中使用,我们可以通过 " super.xxx " 的方式来直接访问子类继承父类的方法,甚至是静态方法。

但是super不能代表类名去使用。

我在父类和子类中写了两个名字一样的方法,而我们使用super就可以来区分父类方法和子类方法

代码如下

public class Inheritance
{
	public static void main(String[] args) 
	{
		Dog mo = new Dog();
		Dog kupurk = new Dog("kupurk","二哈");
		System.out.println(kupurk);
		kupurk.sonfade();
		mo.fatherfade();
	}
}

class Animal
{
	private String name;
	private String type;
	public Animal()
	{
		System.out.println("---父类无参构造执行---");
	}
	public Animal(String name,String type)
	{
		this.name = name;
		this.type = type;
		System.out.println("---父类的有参构造执行---");
	}
	public void fade()
	{
		System.out.println("---父类fade away---");
	}
	public String toString()
	{
		return "["+ name + "," + type + "]";
	}
}
class Dog extends Animal
{
	public void fade()
	{
		System.out.println("---子类fade away---");
	}
	public void fatherfade ()
	{
		super.fade();
	}
	public void sonfade()
	{
		fade();
	}
	public Dog()
	{
		super();
		System.out.println("---子类无参构造方法执行---");
	}
	public Dog(String name,String type)
	{
		super(name,type);
		System.out.println("---子类有参构造方法执行---");
	}
}

输出结果

---父类无参构造执行---
---子类无参构造方法执行---
---父类的有参构造执行---
---子类有参构造方法执行---
[kupurk,二哈]
---子类fade away---
---父类fade away---

所以当我们父类和子类拥有相同名字的方法时,我们要用super来区分父类和子类方法。

如果不加super,会自动默认为子类的方法。

子类的方法,我们可以加以this修饰

父类调用: super.xxxx

子类调用: this.xxxx(this可去省略)

我们之前也说了super关键字可以用于调用父类的静态函数,这也是因为super是代表了父类的特征,所以super关键字可以调用,

而this关键字不可。

注意若方法在父类中被private修饰,在子类中用super关键字也无法对他进行调用。

我们将父类中的fade方法用private修饰

private void fade()
{
	System.out.println("---父类fade away---");
}

输出结果

Inheritance.java:44: 错误: fade() 在 Animal 中是 private 访问控制
                super.fade();
                     ^
1 个错误

所以方法在父类中被private修饰,在子类中用super关键字也无法对他进行调用。只可以通过其他public方法进行间接访问

9.4 Object类

​ 在了解到super()之后,我们明白了一个类的构造函数中会自动隐含一个父类的构造器。

这么说的话,我们第一个定义的类,也应该有一个父类才对,也就是说存在一个 “万恶之源”-----“类的祖宗”。

我们可以在jdk目录下找到scr文件 里面有java的源代码,打开Object.java就能看到里面的源代码了

我们需要知道所有类都是由Object类继承而来,Object类就是老祖宗类

Object类中特征可以被他的所有子类公用,如toString();

标签:Java,String,之旅,子类,---,Part,父类,super,public
来源: https://blog.csdn.net/u014568597/article/details/113358938

专注分享技术,共同学习,共同进步。侵权联系[admin#icode9.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有