【java基础】面向对象的三大基本特征之-------继承
面向对象的三大特征:封装,继承,多态
java通过extends关键字来实现继承,而且是单继承,一个子类只可以有一个直接父类,但是父类还可以有父类...
java.long.Object是所有类的父类,如果一个类没有声明继承于谁,那么默认就是继承于java.long.Object类
通过继承,子类可以获得父类的全部的属性和方法,同时进行拓展。
代码示例:
1 package extendss; 2 3 /** 4 * 类的继承演示代码 5 * 这是一个父类 train 火车类 6 * 默认继承于Object类 7 * 8 * */ 9 public class Train { 10 11 //属性 12 private String trainsNum;//火车编号 13 14 private String trainsCount;//火车数量 15 16 private String trainsType;//车厢类型 17 18 //方法 19 //因为我自己在封装的时候有点迷... 20 //所以写了两个方法,想解决一点疑惑 21 //在自己的方法内调用自己的属性 22 //不需要通过get方法... 23 public void speakInfo1(){ 24 System.out.println(this.getTrainsNum() + "列车是由" + this.getTrainsCount() + "节" 25 + this.getTrainsType() + "型车厢组成的"); 26 } 27 28 public void speakInfo2(){ 29 System.out.println(trainsNum + "列车是由" + trainsCount + "节" 30 + trainsType + "型车厢组成的"); 31 } 32 33 34 /**----------get/set方法------------**/ 35 36 public String getTrainsNum() { 37 return trainsNum; 38 } 39 40 public void setTrainsNum(String trainsNum) { 41 this.trainsNum = trainsNum; 42 } 43 44 public String getTrainsCount() { 45 return trainsCount; 46 } 47 48 public void setTrainsCount(String trainsCount) { 49 this.trainsCount = trainsCount; 50 } 51 52 public String getTrainsType() { 53 return trainsType; 54 } 55 56 public void setTrainsType(String trainsType) { 57 this.trainsType = trainsType; 58 } 59 60 }
package extendss; /** * 这是子类 客运列车类 * 继承于 Train类 * */ public class PassengerTrain extends Train { //暂时是空方法 public static void main(String[] args) { //因为继承了Train类,所以,即使方法是空的,也可以使用父类中的方法 PassengerTrain pt = new PassengerTrain(); //给属性赋值 pt.setTrainsCount("18"); pt.setTrainsNum("K8359/k8360"); pt.setTrainsType("25T"); //调用方法 pt.speakInfo1(); //K8359/k8360列车是由18节25T型车厢组成的 pt.speakInfo2(); //K8359/k8360列车是由18节25T型车厢组成的 } }
即使子类是个空类 也可以通过继承父类 获取属性和方法~~
子类重写父类的方法
子类在拓展父类的属性和方法的同时,也可以对父类中不适用的方法进行重写,但必须是与父类方法方法名相同,形参列表也要相同
子类重写了父类的方法,此时,再想使用父类中的方法,可以通过关键字super调用...
对于static修饰的类方法,则可以直接使用父类名调用。
代码示例
package extendss; /** * 这是子类 客运列车类 * 继承于 Train类 * */ public class PassengerTrain extends Train { //拓展的属性 private String Trainload;//载客量 //重写父类中的方法 public void speakInfo1(){ System.out.println(this.getTrainsNum() + "列车是由" + this.getTrainsCount() + "节" + this.getTrainsType() + "型车厢组成的,一共可以乘坐" + Trainload + "位乘客"); } //super调用父类中的方法 public void speakInfoFU(){ super.speakInfo1(); } public static void main(String[] args) { //因为继承了Train类,所以,即使方法是空的,也可以使用父类中的方法 PassengerTrain pt = new PassengerTrain(); //给属性赋值 pt.setTrainsCount("18"); pt.setTrainsNum("K8359/k8360"); pt.setTrainsType("25T"); //调用方法 这里先注释了 //pt.speakInfo1(); //pt.speakInfo2(); /*------------------------------*/ //给拓展的属性赋值 pt.Trainload = "2056"; //调用子类重写的方法 pt.speakInfo1(); // K8359/k8360列车是由18节25T型车厢组成的,一共可以乘坐2056位乘客
//调用父类原有方法 pt.speakInfoFU(); //K8359/k8360列车是由18节25T型车厢组成的 } }
车次是真的...车型也是真的...乘客数是按定员118 餐车50算的...纯属娱乐~~
子类利用super调用父类的构造函数
在子类的构造函数中 可以利用super调用父类的构造函数,但是利用super调用父类构造函数必须出现在子类构造函数的第一行。
代码示例:
package superss; /** * 父对象 * * */ public class Fu { //构造函数 public Fu(){ System.out.println("父对象里的无参构造函数"); } public Fu(String A1){ this(); this.A1 = A1; System.out.println("父对象里的带一个参数的构造函数"); } public Fu(String A1,String A2){ this(A1); this.A2 = A2; System.out.println("父对象里的带辆个参数的构造函数"); } //定义属性 public String A1; public String A2; }
package superss; public class Zi extends Fu { //定义构造函数 public Zi (String A1,String A2,String A3) { //调用父类构造函数 super(A1, A2); this.A3 = A3; System.out.println("子类中的构造函数"); } //定义属性 public String A3; //定义方法 public void info(){ System.out.println("子类中的方法"); } public static void main(String[] args) { System.out.println("----------"); Zi zi = new Zi("A1", "A2", "A3"); System.out.println("----------"); zi.info(); } //运行结果: //---------- //父对象里的无参构造函数 //父对象里的带一个参数的构造函数 //父对象里的带辆个参数的构造函数 //子类中的构造函数 //---------- //子类中的方法 }
创建对象总是从该类所在继承树最顶层构造器开始执行,然后依次向下执行,最后执行本类构造器,某个父类通过this调用了同类中的其他构造函数,就会依次执行该父类的多个构造函数