java 面向对象1之继承
------------恢复内容开始------------
首先是需要创建的类,统一创建在oopTest包下:
student类为父类,smallStudent类与bigStudent类继续student类。
student类的代码如下,其中有姓名和成绩两个属性并带有一个显示的方法
1 package oopTest; 2 3 public class Student { 4 String name; 5 double score; 6 public String getName() { 7 return name; 8 } 9 public void setName(String name) { 10 this.name = name; 11 } 12 public double getScore() { 13 return score; 14 } 15 public void setScore(double score) { 16 this.score = score; 17 } 18 public void showScore() { 19 System.out.println("姓名为:" + name + "\t成绩为:" + score); 20 } 21 }
smallStudent类的代码如下,自带的方法为music(),唱跳.....
1 package oopTest; 2 3 public class smallStudent extends Student{ 4 public void music() { 5 System.out.println("小学生会音乐"); 6 } 7 }
bigStudent类的代码如下,自带的方法为reading(),疯狂阅读...
1 package oopTest; 2 3 public class bigStudent extends Student{ 4 public void reading() { 5 System.out.println("大学生会阅读"); 6 } 7 }
最后需要一个测试类来测试子类继续的属性与方法,代码如下
1 package oopTest; 2 3 public class TestExtendsMain { 4 public static void main(String[] args) { 5 smallStudent smalls = new smallStudent(); 6 smalls.setName("小学生"); 7 smalls.setScore(90); 8 smalls.music(); 9 smalls.showScore(); 10 11 bigStudent bigs = new bigStudent(); 12 bigs.setName("大学生"); 13 bigs.setScore(100); 14 bigs.reading(); 15 bigs.showScore(); 16 } 17 }
运行结果和预料的一样,这是最基本的类继承的常识,不多说(下面开始剖析this(),super()还有构造方法与继承的关系)
1 package oopTest; 2 3 public class TestExtendsMain { 4 public static void main(String[] args) { 5 smallStudent smalls = new smallStudent(); 6 smalls.setName("小学生"); 7 smalls.setScore(90); 8 smalls.music(); 9 smalls.showScore(); 10 11 bigStudent bigs = new bigStudent(); 12 bigs.setName("大学生"); 13 bigs.setScore(100); 14 bigs.reading(); 15 bigs.showScore(); 16 } 17 }
先贴上上面代码的继承关系图
开始今天的重点,this(),super()
this(),测试的代码如下,初始化子类smallStudent
1 package oopTest; 2 3 public class TestExtendsMain { 4 public static void main(String[] args) { 5 smallStudent smalls = new smallStudent(); 6 } 7 }
为父类student添加一个无参构造方法并显示出来
1 package oopTest; 2 3 public class Student { 4 String name; 5 double score; 6 public String getName() { 7 return name; 8 } 9 public void setName(String name) { 10 this.name = name; 11 } 12 public double getScore() { 13 return score; 14 } 15 public void setScore(double score) { 16 this.score = score; 17 } 18 public void showScore() { 19 System.out.println("姓名为:" + name + "\t成绩为:" + score); 20 } 21 public Student() { 22 System.out.println("调用父类的无参构造方法"); 23 } 24 }
为子类smallstudent分别添加一个无参构造方法和有参构造方法,并在无参构造方法中使用this()调用有参构造方法
1 package oopTest; 2 3 public class smallStudent extends Student{ 4 public void music() { 5 System.out.println("小学生会音乐"); 6 } 7 public smallStudent() { 8 this("jump"); 9 System.out.println("子类的无参构造方法"); 10 } 11 public smallStudent(String behavior) { 12 System.out.println("子类的有参构造方法"); 13 } 14 }
看看结果,可以知道子类的构造方法在初始化时会先调用父类的无参构造方法,而this()可以通过输入的参数调用本类相应的构造方法
注意:this()与super()调用的构造方法必须存在且在构造方法的最顶层否则会报错,如下初始化错误
看看super()方法,依旧是通过初始化一个子类的方式来看
1 package oopTest; 2 3 public class TestExtendsMain { 4 public static void main(String[] args) { 5 smallStudent smalls = new smallStudent(); 6 } 7 }
父类依旧
1 package oopTest; 2 3 public class Student { 4 String name; 5 double score; 6 public String getName() { 7 return name; 8 } 9 public void setName(String name) { 10 this.name = name; 11 } 12 public double getScore() { 13 return score; 14 } 15 public void setScore(double score) { 16 this.score = score; 17 } 18 public void showScore() { 19 System.out.println("姓名为:" + name + "\t成绩为:" + score); 20 } 21 public Student() { 22 System.out.println("调用父类的无参构造方法"); 23 } 24 }
将子类的this()方法改为super()
1 package oopTest; 2 3 public class smallStudent extends Student{ 4 public void music() { 5 System.out.println("小学生会音乐"); 6 } 7 public smallStudent() { 8 super(); 9 System.out.println("子类的无参构造方法"); 10 } 11 public smallStudent(String behavior) { 12 System.out.println("子类的有参构造方法"); 13 } 14 }
运行结果如下,说明子类的构造器在初始化时会在顶层默认调用super()方法
以下代码使用子类的有参构造方法进行初始化,并没有写下super(),结果依然调用了父类的无参构造方法
1 package oopTest; 2 3 public class TestExtendsMain { 4 public static void main(String[] args) { 5 smallStudent smalls = new smallStudent("jump"); 6 } 7 }
1 package oopTest; 2 3 public class smallStudent extends Student{ 4 public void music() { 5 System.out.println("小学生会音乐"); 6 } 7 public smallStudent() { 8 System.out.println("子类的无参构造方法"); 9 } 10 public smallStudent(String behavior) { 11 System.out.println("子类的有参构造方法"); 12 } 13 }
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
接下来创建三个类,a,b,c类,a继承b类,b类继承c类
以下为a类的代码,只有一个无参构造方法
1 package oopTest; 2 3 public class a { 4 public a() { 5 System.out.println("我是a类的无参构造方法"); 6 } 7 }
以下为b类的代码,提供一个无参的构造方法
1 package oopTest; 2 3 public class b extends a{ 4 public b() { 5 System.out.println("调用了b类的无参构造方法"); 6 } 7 }
以下为c类的代码,提供一个无参与有参的构造方法
1 package oopTest; 2 3 public class c extends b{ 4 public c() { 5 this("string"); 6 System.out.println("调用了c类的无参构造方法"); 7 } 8 public c(String args) { 9 System.out.println("调用类c类的有参构造方法"); 10 } 11 }
测试代码,初始化一个c类
1 package oopTest; 2 3 public class TestExtendsMain { 4 public static void main(String[] args) { 5 c c1 = new c(); 6 } 7 }
可以推测一下结果,首先初始化c类的构造器,但是因为c类继承类b类,所以先初始化b类的构造器,以此类推,a类的无参构造方法--》b类的无参构造方法--》c类的有参构造方法--》c类的无参构造方法
运行结果为
可以发现结果是调用了c类的父类b类与它的父类a类的“一个”构造方法,当然它也只有一个构造方法于是给a类和b类写上一个有参的构造方法,看看会不会在初始化时调用父类的两个构造方法
代码如下,分别在a类和b类创建了有参的构造方法
1 package oopTest; 2 3 public class a { 4 public a() { 5 System.out.println("我是a类的无参构造方法"); 6 } 7 public a(String args) { 8 System.out.println("我是a类的有参构造方法"); 9 } 10 }
1 package oopTest; 2 3 public class b extends a{ 4 public b() { 5 System.out.println("调用了b类的无参构造方法"); 6 } 7 public b(String args) { 8 System.out.println("调用类b类的有参构造方法"); 9 } 10 }
在c类的无参构造方法中使用super(),结果如下
1 package oopTest; 2 3 public class c extends b{ 4 public c() { 5 super(); 6 System.out.println("调用了c类的无参构造方法"); 7 } 8 public c(String args) { 9 System.out.println("调用类c类的有参构造方法"); 10 } 11 }
如果给c类的super()加上参数会怎么样?
1 package oopTest; 2 3 public class c extends b{ 4 public c() { 5 super("string"); 6 System.out.println("调用了c类的无参构造方法"); 7 } 8 public c(String args) { 9 System.out.println("调用类c类的有参构造方法"); 10 } 11 }
通过结果可以看到,c类的super(string)调用了父类b类的“一个”有参构造方法,证明父类只会调用一个构造方法?
我们试试以下这段代码
1 package oopTest; 2 3 public class c extends b{ 4 public c() { 5 this("string"); 6 System.out.println("调用了c类的无参构造方法"); 7 } 8 public c(String args) { 9 super("string"); 10 System.out.println("调用类c类的有参构造方法"); 11 } 12 }
通过初始化c类的无参构造方法,运行的顺序为 a类的无参构造方法--》b类的无参构造方法--》c类的有参构造方法--》b类的有参构造方法--》c类的有参构造方法
结果为
从上面的运行顺序来看,b类的无参构造方法确实调用了(临时),但是在之后它被b类的有参构造方法顶替了,而a类即使有两个构造方法也没有被顶替掉,由此可见,父类的构造器在初始化时只会把最后调用的一个构造器显示出来。
最后,我们如果在b类的有参构造方法中使用super()调用a类的有参构造方法是否也会这样呢?
1 package oopTest; 2 3 public class b extends a{ 4 public b() { 5 System.out.println("调用了b类的无参构造方法"); 6 } 7 public b(String args) { 8 super("string"); 9 System.out.println("调用类b类的有参构造方法"); 10 } 11 }
结果是肯定的,a类的无参构造方法被销毁了(也许是被重载了这部分我也有点迷),谢谢耐心观看本篇文章的小伙伴们,下一篇,封装!!