zoukankan      html  css  js  c++  java
  • java7-3 继承

    1、继承概述:

    把多个类中相同的内容给提取出来定义到一个类中。

    如何实现继承呢?

    Java提供了关键字:extends

    格式:

    class 子类名 extends 父类名 {}

    父类也称为基类、超类;子类也称为派生类

    好处:

    A:提高了代码的复用性

    B:提高了代码的维护性

    C:让类与类之间产生了关系,是多态的前提

    而类与类产生了关系,其实也是继承的一个弊端:

    类的耦合性增强了。

    开发的原则:低耦合,高内聚。

    耦合:类与类的关系

    内聚:就是自己完成某件事情的能力

    1、例子

     1 //使用继承前
     2 
     3 /*
     4 
     5 class Student {
     6 
     7 public void eat() {
     8 
     9 System.out.println("吃饭");
    10 
    11 }
    12 public void sleep() {
    13 
    14 System.out.println("睡觉");
    15 
    16 }
    17 
    18 }
    19 class Teacher {
    20 
    21 public void eat() {
    22 
    23 System.out.println("吃饭");
    24 
    25 }
    26 
    27 public void sleep() {
    28 
    29 System.out.println("睡觉");
    30 
    31 }
    32 
    33 }
    34 
    35 */
    36 
    37 //使用继承后
    38 
    39 class Person {
    40 
    41 public void eat() {
    42 
    43 System.out.println("吃饭");
    44 
    45 }
    46 
    47 public void sleep() {
    48 
    49 System.out.println("睡觉");
    50 
    51 }
    52 
    53 }
    54 class Student extends Person {}
    55 class Teacher extends Person {}
    56 class ExtendsDemo {
    57 
    58 public static void main(String[] args) {
    59 
    60 Student s = new Student();
    61 
    62 s.eat();
    63 
    64 s.sleep();
    65 
    66 System.out.println("-------------");
    67 
    68 Teacher t = new Teacher();
    69 
    70 t.eat();
    71 
    72 t.sleep();
    73 
    74 }
    75 
    76 }

    2、Java中继承的特点:
    A:Java只支持单继承,不支持多继承。

    有些语言是支持多继承,格式:extends 类1,类2,...

    B:Java支持多层继承(继承体系)

     1 /*
     2 
     3 class Father {}
     4 
     5 class Mother {}
     6 
     7 class Son exnteds Father {} //正确的
     8 
     9 class Son extends Father,Mother {} // 错误的
    10 
    11 */
    12 
    13 class GrandFather {
    14 
    15 public void show() {
    16 
    17 System.out.println("我是爷爷");
    18 
    19 }
    20 
    21 }
    22 
    23 class Father extends GrandFather {
    24 
    25 public void method(){
    26 
    27 System.out.println("我是老子");
    28 
    29 }
    30 
    31 }
    32 
    33 class Son extends Father {}
    34 
    35 class ExtendsDemo2 {
    36 
    37 public static void main(String[] args) {
    38 
    39 Son s = new Son();
    40 
    41 s.method(); //使用父亲的
    42 
    43 s.show(); //使用爷爷的
    44 
    45 }
    46 
    47 }

    3、继承的注意事项:

    A:子类只能继承父类所有非私有的成员(成员方法和成员变量)

    B:子类不能继承父类的构造方法,但是可以通过super(马上讲)关键字去访问父类构造方法。

    C:不要为了部分功能而去继承

    class A {

    public void show1(){}

    public void show2(){}

    }

    class B {

    public void show2(){}

    public void show3(){}

    }

    //我们发现B类中出现了和A类一样的show2()方法,所以,我们就用继承来体现

    class B extends A {

    public void show3(){}

    }

    这样其实不好,因为这样你不但有了show2(),还多了show1()。
    有可能show1()不是你想要的。

    那么,我们什么时候考虑使用继承呢?

    继承其实体现的是一种关系:"is a"。

    Person Student Teacher

    水果 苹果 香蕉 橘子

    采用假设法。

    如果有两个类A,B。只有他们符合A是B的一种,或者B是A的一种,就可以考虑使用继承。

     1 class Father {
     2 
     3 private int num = 10;
     4 
     5 public int num2 = 20;
     6 
     7 //私有方法,子类不能继承
     8 
     9 private void method() {
    10 
    11 System.out.println(num);
    12 
    13 System.out.println(num2);
    14 
    15 }
    16 
    17 public void show() {
    18 
    19 System.out.println(num);
    20 
    21 System.out.println(num2);
    22 
    23 }
    24 
    25 }
    26 
    27 class Son extends Father {
    28 
    29 public void function() {
    30 
    31 //num可以在Father中访问private
    32 
    33 //System.out.println(num); //子类不能继承父类的私有成员变量
    34 
    35 System.out.println(num2);
    36 
    37 }
    38 
    39 }
    40 
    41 class ExtendsDemo3 {
    42 
    43 public static void main(String[] args) {
    44 
    45 // 创建对象
    46 
    47 Son s = new Son();
    48 
    49 //s.method(); //子类不能继承父类的私有成员方法
    50 
    51 s.show();
    52 
    53 s.function();
    54 
    55 }
    56 
    57 }

    4、类的组成:

    成员变量:

    构造方法:

    成员方法:

    而现在我们又讲解了继承,所以,我们就应该来考虑一下,类的组成部分的各自关系。

    继承中成员变量的关系:

    A:子类中的成员变量和父类中的成员变量名称不一样,这个太简单。

    B:子类中的成员变量和父类中的成员变量名称一样,这个怎么玩呢?

    在子类方法中访问一个变量的查找顺序:(就近原则)

    a:在子类方法的局部范围找,有就使用

    b:在子类的成员范围找,有就使用

    c:在父类的成员范围找,有就使用

    d:如果还找不到,就报错。

     1 class Father {
     2 
     3 public void show() {
     4 
     5 System.out.println("show Father");
     6 
     7 }
     8 
     9 }
    10 
    11 class Son extends Father {
    12 
    13 public void method() {
    14 
    15 System.out.println("method Son");
    16 
    17 }
    18 
    19 public void show() {
    20 
    21 System.out.println("show Son");
    22 
    23 }
    24 
    25 }
    26 
    27 class ExtendsDemo4 {
    28 
    29 public static void main(String[] args) {
    30 
    31 //创建对象
    32 
    33 Son s = new Son();
    34 
    35 s.show();
    36 
    37 s.method();
    38 
    39 //s.fucntion(); //找不到符号
    40 
    41 }
    42 
    43 }
    44 
    45 }//结果是: show Son methor Son //名字一样,如果子类中有,先调子类

    5、 我不仅仅要输出局部范围的num,还要输出本类成员范围的num。怎么办呢?
    我还想要输出父类成员范围的num。怎么办呢?

    如果有一个东西和this相似,但是可以直接访问父类的数据就好了。

    恭喜你,这个关键字是存在的:super。

    this和super的区别?

    分别是什么呢?

    this代表本类对应的引用。

    super代表父类存储空间的标识(可以理解为父类引用,可以操作父类的成员)

    怎么用呢?

    A:调用成员变量

    this.成员变量 调用本类的成员变量

    super.成员变量 调用父类的成员变量

    B:调用构造方法

    this(...) 调用本类的构造方法

    super(...) 调用父类的构造方法

    C:调用成员方法

    this.成员方法 调用本类的成员方法

    super.成员方法 调用父类的成员方法

     1 class Father {
     2 
     3 public int num = 10;
     4 
     5 }
     6 
     7 class Son extends Father {
     8 
     9 public int num = 20;
    10 
    11 public void show() {
    12 
    13 int num = 30;
    14 
    15 System.out.println(num);
    16 
    17 System.out.println(this.num);
    18 
    19 System.out.println(super.num);
    20 
    21 }
    22 
    23 }
    24 
    25 class ExtendsDemo5 {
    26 
    27 public static void main(String[] args) {
    28 
    29 Son s = new Son();
    30 
    31 s.show();
    32 
    33 }
    34 
    35 }

    6、继承中构造方法的关系
    A:子类中所有的构造方法默认都会访问父类中空参数的构造方法

    B:为什么呢?

    因为子类会继承父类中的数据,可能还会使用父类的数据。

    所以,子类初始化之前,一定要先完成父类数据的初始化。

    注意:子类每一个构造方法的第一条语句默认都是:super();

     1 class Father {
     2 
     3 int age;
     4 
     5 public Father() {
     6 
     7 System.out.println("Father的无参构造方法");
     8 
     9 }
    10 
    11 public Father(String name) {
    12 
    13 System.out.println("Father的带参构造方法");
    14 
    15 }
    16 
    17 }
    18 
    19 class Son extends Father {
    20 
    21 public Son() {
    22 
    23 //super();这个不写都默认有
    24 
    25 System.out.println("Son的无参构造方法");
    26 
    27 }
    28 
    29 public Son(String name) {
    30 
    31 //super();这个不写都默认有
    32 
    33 System.out.println("Son的带参构造方法");
    34 
    35 }
    36 
    37 }
    38 
    39 class ExtendsDemo6 {
    40 
    41 public static void main(String[] args) {
    42 
    43 //创建对象
    44 
    45 Son s = new Son();
    46 
    47 System.out.println("------------");
    48 
    49 Son s2 = new Son("林青霞");
    50 
    51 }
    52 
    53 }

    7、如果父类没有无参构造方法,那么子类的构造方法会出现什么现象呢?
    报错。

    如何解决呢?

    A:在父类中加一个无参构造方法

    B:通过使用super关键字去显示的调用父类的带参构造方法

    C:子类通过this去调用本类的其他构造方法

    子类中一定要有一个去访问了父类的构造方法,否则父类数据就没有初始化,就出错。

    注意事项:

    this(...)或者super(...)必须出现在第一条语句上。

    如果不是放在第一条语句上,就可能对父类的数据进行了多次初始化,所以必须放在第一条语句上。

     1 class Father {
     2 
     3 /*
     4 
     5 public Father() {
     6 
     7 System.out.println("Father的无参构造方法");
     8 
     9 }
    10 
    11 */
    12 
    13 public Father(String name) {
    14 
    15 System.out.println("Father的带参构造方法");
    16 
    17 }
    18 
    19 }
    20 
    21 class Son extends Father {
    22 
    23 public Son() {
    24 
    25 super("随便给");
    26 
    27 System.out.println("Son的无参构造方法");
    28 
    29 //super("随便给");
    30 
    31 }
    32 
    33 public Son(String name) {
    34 
    35 //super("随便给");
    36 
    37 this();
    38 
    39 System.out.println("Son的带参构造方法");
    40 
    41 }
    42 
    43 }
    44 
    45 class ExtendsDemo7 {
    46 
    47 public static void main(String[] args) {
    48 
    49 Son s = new Son();
    50 
    51 System.out.println("----------------");
    52 
    53 Son ss = new Son("林青霞");
    54 
    55 }
    56 
    57 }

    8、方法重写:子类中出现了和父类中方法声明一模一样的方法。

    方法重载:本类中出现的方法名一样,参数列表不同的方法。与返回值无关。

    子类对象调用方法的时候:先找子类本身,再找父类。

    方法重写的应用:当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法。

    这样,即沿袭了父类的功能,又定义了子类特有的内容。

    案例:

    A:定义一个手机类。

    B:通过研究,我发明了一个新手机,这个手机的作用是在打完电话后,可以听天气预报。

    按照我们基本的设计,我们把代码给写出来了。

    但是呢?我们又发现新手机应该是手机,所以,它应该继承自手机。

    其实这个时候的设计,并不是最好的。

    因为手机打电话功能,是手机本身就具备的最基本的功能。

    所以,我的新手机是不用在提供这个功能的。

    但是,这个时候,打电话功能就没有了。这个不好。

    最终,还是加上这个功能。由于它继承了手机类,所以,我们就直接使用父类的功能即可。

    那么,如何使用父类的功能呢?通过super关键字调用

     1 class Phone1{
     2 
     3 public void show(String name){
     4 
     5 System.out.println("给"+name+"打电话");
     6 
     7 }
     8 
     9 }
    10 
    11 class Phone2 extends Phone1{
    12 
    13 public void show(String name){
    14 
    15 super.show(name);// 继承Phone1类的show方法,
    16 
    17 //System.out.println("给"+name+"打电话");
    18 
    19 System.out.println("还可以发短信");
    20 
    21 }
    22 
    23 }
    24 
    25 class ExtendsDemo1{
    26 
    27 public static void main(String[] args){
    28 
    29 new Phone2().show("阿三");
    30 
    31 }
    32 
    33 }

    9、方法重写的注意事项
    A:父类中私有方法不能被重写

    因为父类私有方法子类根本就无法继承

    B:子类重写父类方法时,访问权限不能更低。就是子类的方法权限不能比父类的低。

    最好两者一致。

    C:父类静态方法,子类也必须通过静态方法进行重写

    其实这个算不上方法重写,但是现象确实如此,至于为什么算不上方法重写,多态中我会讲解

    子类重写父类方法的时候,最好声明一模一样。

    何事都只需坚持.. 难? 维熟尔。 LZL的自学历程...只需坚持
  • 相关阅读:
    time 模块学习
    day 14 自定义模块,常用模块 time .datetime ,time 模块
    day 13 课后作业
    day 12 课后作业
    day 11课后作业
    树状数组最值
    hdu 1059 Dividing bitset 多重背包
    XVII Open Cup named after E.V. Pankratiev. XXI Ural Championship
    最长公共子序列板/滚动 N^2
    Uva 10635
  • 原文地址:https://www.cnblogs.com/LZL-student/p/5858762.html
Copyright © 2011-2022 走看看