继承可以解决代码的复用,让我们的编程更加靠近人类思维,当多个类存在相同的属性和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过extends语句来声明继承。

 

注意事项

Ⅰ.java 中支持单继承,不直接支持多继承,但对c++中的多继承机制进行改良。

Ⅱ.ava支持多层(多重)继承

Ⅲ.Java所有类都是Object类的子类

Ⅳ.JDK中有202个包3777个类、接口、异常、枚举、注释和错误

实例

 1 package com.beekc.www;
 2 
 3 public class Beekc {
 4     public static void main(String[] args) {
 5         Pupil stu1 = new Pupil();
 6         stu1.pay(500);
 7         stu1.printName();
 8         stu1.printFee();
 9 
10         MiddleStu stu2 = new MiddleStu();
11         stu2.pay(500);
12         stu2.printName();
13         stu2.printFee();
14 
15         ColStu stu3 = new ColStu();
16         stu3.pay(500);
17         stu3.printName();
18         stu3.printFee();
19     }
20 }
21 
22 //将学生的共有属性提出,做一个父类
23 class Stu
24 {
25     protected int age;
26     public String name;
27     public float fee;
28     //编程中,如果你不希望子类继承某个属性或者方法
29     //将其声明为private
30     private String job;
31 
32     public void printName()
33     {
34         System.out.printf("名字:" + this.name + "\t");
35     }
36     public void printFee()
37     {
38         System.out.println("交费" + this.fee + "¥");
39     }
40 }
41 
42 //小学生类
43 class Pupil extends Stu
44 {
45     public Pupil()
46     {
47         name = "小学生";
48     }
49     //交费
50     public void pay(float fee)
51     {
52         this.fee = fee;
53     }
54 }
55 
56 //中学生类
57 class MiddleStu extends Stu
58 {
59     public MiddleStu()
60     {
61         name = "中学生";
62     }
63     //交费
64     public void pay(float fee)
65     {
66         this.fee = fee * 0.8f;
67     }
68 }
69 
70 //大学生类
71 class ColStu extends Stu
72 {
73     public ColStu()
74     {
75         name = "大学生";
76     }
77     //交费
78     public void pay(float fee)
79     {
80         this.fee = fee * 0.6f;
81     }
82 }

运行结果

 

 

 

继承的细节

 1 //第一种情况:当子类与父类的变量的名称相同时,在子类里想用父类的变量时用super关键字
 2 public class Father {
 3     int num = 4;
 4 }
 5 
 6 public class Son extends Father {
 7     int num = 5;
 8     public void show()
 9     {
10         System.out.println(this.num + "..." + super.num);
11     }
12 }
13 
14 public class ExtendsDemo {
15     public static void main(String[] args)
16     {
17         Son son = new Son();
18         son.show();
19 
20     }
21 }

 

 1 //第二种情况:当父类的方法与子类的方法想同时,子类的方法会去覆盖父类的方法,这里会去输出子的内容,想要用父类的方法用super关键字
 2 public class Father {
 3     public void show()
 4     {
 5         System.out.println("Father run ...");
 6     }
 7 }
 8 
 9 public class Son extends Father {
10     public void show()
11     {
12         System.out.println("Son run ...");
13     }
14 }
15 
16 public class ExtendsDemo {
17     public static void main(String[] args)
18     {
19         new Son().show();
20     }
21 }

 

 1 //第三种情况:子类方法覆盖父类方法时,子类权限必须要大于等于父类的权限
 2 //这个程序会报错
 3 public class Father {
 4     public void show() //这里权限是public
 5     {
 6         System.out.println("Father run ...");
 7     }
 8 }
 9 
10 public class Son extends Father {
11     private void show()//这里权限是private
12     {
13         System.out.println("Son run ...");
14     }
15 }
16 
17 public class ExtendsDemo {
18     public static void main(String[] args)
19     {
20         new Son().show();
21     }
22 }
//会报错的程序:静态方法只能覆盖静态方法,或被静态覆盖
class Father
{
    public static void show()
    {
        System.out.println("run show");
    }
}

class Son extends Father
{
     public void show()
    {
        System.out.println("run show");
    }
}

class ExtendsDome
{
    public static void main(String[] args)
    {
        Son son = new Son();
        son.show();
    }
}

 

 1 //第四种情况:会报错的程序:静态方法只能覆盖静态方法,或被静态覆盖
 2 class Father
 3 {
 4     public static void show()
 5     {
 6         System.out.println("run show");
 7     }
 8 }
 9 
10 class Son extends Father
11 {
12      public void show()
13     {
14         System.out.println("run show");
15     }
16 }
17 
18 class ExtendsDome
19 {
20     public static void main(String[] args)
21     {
22         Son son = new Son();
23         son.show();
24     }
25 }

什么时候使用覆盖操作?
当对一个类进行子类的扩展时,子类需要保留父类的功能声明。但是要定义子类中该功能的特有内容时,就使用覆盖操作完成。

 

子父类中的构造函数的特点

在子类构造对象时,发现,访问子类构造函数时,父类也运行。为什么呢?原因是:在子类的构造函数中第一行有一个默认的隐式语句。super();

子类的实例化过程,子类中的构造函数默认都会访问父类中的空参数构造函数.

 1 class Father
 2 {
 3     Father()
 4     {
 5         System.out.println("Father run");
 6     }
 7 }
 8 
 9 class Son extends Father
10 {
11     Son()
12     {
13         //super(); //隐藏的语句,此语句是调用父类的空参数构造函数
14         System.out.println("Son run");
15         //return;
16     }
17 }
18 
19 class ExtendsDome
20 {
21     public static void main(String[] args)
22     {
23         new Son();
24     }
25 }
26 
27 //运行结果
28 //Father run
29 //Son run

 

为什么子类实例化的时候要访问父类的构造函数呢?

那是因为子类继承了父类,获取到了父类的内容(属性),所以在使用父亲内容之前,要先看父类如何对自己的内容进行初始化的。所以子类在构造对象时,必须访问父类中的构造函数。为什么完成这个必须的动作,就在子类的构造函数中加入了super()语句。 如果父类中没有定义空参数构造函数,那么子类的构造函数必须用super明确要掉调用父类中哪个构造函数.同时子类构造函数中如果使用this调用了本类构造函数时,那么super就没有被替换了,因为super和this只能定义在第一行,所以只能有一个。但是可以保证的是,子类中肯定会有其他的构造函数访问父类的构造函数。注意的是super语句必须要定义在子类构造函数的第一行,因为父类的初始化动作要先完成。

 1 class Father
 2 {
 3     Father()
 4     {
 5         System.out.println("Father run");
 6     }
 7     Father(int x)
 8     {
 9         System.out.println("Father run ..." + x);
10     }
11 }
12 
13 class Son extends Father
14 {
15     Son()
16     {
17         //super();//这里回去初始化父类的构造函数
18         System.out.println("Son run");
19         return;
20     }
21     Son(int x)
22     {
23         this();
24         //super();//这里的super()会被替换,因为this()与super()只能写在第一行。
25         System.out.println("Son run ..." + x);
26         return;
27     }
28 }
29 
30 class ExtendsDome
31 {
32     public static void main(Sring[] args)
33     {
34         new Son(6);
35     }
36 }
37 
38 //运行结果
39 //Father run
40 //Son run
41 //Son run ...6

 

 1 class Father
 2 {
 3     Father()
 4     {
 5         super();
 6         show();
 7         return;
 8     }
 9     
10     public void show()
11     {
12         System.out.println("Father show");
13     }
14 }
15 
16 class Son extends Father
17 {
18     int num = 8;
19     
20     Son()
21     {
22         super();
23         //通过super初始化父类时,子类的成员变量并未显示初始化。等super()父类初始化完毕后,才进行子类的成员变量显示初始化。
24         show();
25         return;
26     }
27     public void show()
28     {
29         System.out.println("Son show ..." + num);
30     }
31 }
32 
33 class ExtendsDome
34 {
35     public static viod main(String[] args)
36     {
37         Son son = new Son();
38         son.show();
39     }
40 }
41 
42 //运行结果
43 //Son show ...0
44 //Son show ...8

 

posted on 2020-02-17 16:50  白客C  阅读(159)  评论(0编辑  收藏  举报