标签: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
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。