Java 继承


what: 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。子类从它的父类中继承可访问的数据域和方法,也可以添加新的数据域和新的方法。

why: 继承是 Java 中实现软件重用的重要手段,避免重复,易于维护,易于理解。(共享共同的特征和动作...)

关系:子类继承父类的特征和行为,并可扩展父类。于此,父类更通用,子类更具体。

eg: 开发 动物类,其中动物有分别为企鹅以及老鼠,要求如下:
企鹅:属性(姓名,id),方法(吃,睡,自我介绍)
老鼠:属性(姓名,id),方法(吃,睡,自我介绍)
public class Penguin {
private String name;
private int id;
public Penguin(String myName, int myid) {
name = myName;
id = myid;
}
public void eat(){
System.out.println(name+"正在吃");
}
public void sleep(){
System.out.println(name+"正在睡");
}
public void introduction() {
System.out.println("大家好!我是" + id + "号" + name + ".");
}
}

企鹅类

public class Mouse {
private String name;
private int id;
public Mouse(String myName, int myid) {
name = myName;
id = myid;
}
public void eat(){
System.out.println(name+"正在吃");
}
public void sleep(){
System.out.println(name+"正在睡");
}
public void introduction() {
System.out.println("大家好!我是" + id + "号" + name + ".");
}
}

老鼠类

从这两段代码可以看出来,代码存在重复了,导致后果就是代码量大且臃肿,而且维护性不高(维护性主要是后期需要修改的时候,就需要修改很多的代码,容易出错),所以要从根本上解决这两段代码的问题,就需要继承,将两段代码中相同的部分提取出来组成 一个父类:

public class Animal {
private String name;
private int id;
public Animal(String myName, int myid) {
name = myName;
id = myid;
}
public void eat(){
System.out.println(name+"正在吃");
}
public void sleep(){
System.out.println(name+"正在睡");
}
public void introduction() {
System.out.println("大家好!我是" + id + "号" + name + ".");
}
}

公共父类 - Animal.java

public class Penguin extends Animal {
public Penguin(String myName, int myid) {
super(myName, myid);
}
}

企鹅类(继承父类)- Penguin.java

public class Mouse extends Animal {
public Mouse(String myName, int myid) {
super(myName, myid);
}
}

老鼠类(继承父类)- Mouse.java


继承的特性

  • 子类拥有父类 非private 的属性、方法。

  • 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。

  • 子类可以用自己的方式实现父类的方法。

  • Java 只允许单一继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如A类继承B类,B类继承C类,所以按照关系就是C类是B类的父类,B类是A类的父类,这是java继承区别于C++继承的一个特性。

  • 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系)。


继承关键字

继承可以使用 extends implements 这两个关键字来实现继承,而且所有的类都是继承于 java.lang.Object。当一个类没有继承的两个关键字,则默认继承object(这个类在 java.lang 包中,所以不需要 import)祖先类。

  • extends 关键字:在 Java 中,类的继承是单一继承,也就是说,一个子类只能拥有一个父类,所以 extends 只能继承一个类,格式:

    class 父类 {
    } class 子类 extends 父类 {
    }
    public class Animal {
    private String name;
    private int id;
    public Animal(String myName, String myid) {
    //初始化属性值
    }
    public void eat() { //吃东西方法的具体实现 }
    public void sleep() { //睡觉方法的具体实现 }
    } public class Penguin extends Animal{
    //...
    }

    extends 实例

  • implements 关键字:可以变相的使 java 具有多继承的特性,使用范围为 继承 接口 的情况,可以同时继承多个接口(接口跟接口之间采用逗号分隔)

    public interface A {
    public void eat();
    public void sleep();
    } public interface B {
    public void show();
    } public class C implements A,B {
    }

    implements 实例

  • super 与 this 关键字:可以通过 super 关键字来实现对父类成员的访问,用来引用当前对象的父类。this 关键字指向自己的引用。
    public class SuperDemo {
    public static void main(String []args) {
    new SubClass().showMessage();
    }
    } class SuperClass {
    int i = ;
    } class SubClass extends SuperClass {
    int i =;
    public void showMessage() {
    System.out.printf("super.i = %d, this.i = %d\n", super.i, this.i);
    }
    }

    super & this 说明实例

super 表示使用它的类的父类。super 可用于:

    • 调用父类的构造方法;
    • 调用父类的方法(子类覆盖了父类的方法时);
      class Animal{
      public void move(){
      System.out.println("动物可以移动");
      }
      } class Dog extends Animal{
      public void move(){
      super.move(); // 应用super类的方法
      System.out.println("狗可以跑和走");
      }
      } public class TestDog{
      public static void main(String args[]){ Animal b = new Dog(); // Dog 对象
      b.move(); //执行 Dog类的方法
      }
      } /*运行结果:
      动物可以移动
      狗可以跑和走*/

      子类中调用父类的被重写方法 实例

    • 访问父类的数据域(可以这样用但没有必要这样用)。

调用父类的构造方法语法:super() or super(参数列表);

    • 注意:super 语句必须是子类构造方法的第一条语句。不能在子类中使用父类构造方法名来调用父类构造方法, 父类的构造方法不被子类继承。调用父类的构造方法的唯一途径是使用 super 关键字,如果子类中没显式调用,则编译器自动将 super(); 作为子类构造方法的第一条语句。这会形成一个构造方法链。
    • 静态方法中不能使用 super 关键字。
    • 调用父类的方法语法:super.方法名(参数列表);
    • 如果是继承的方法,是没有必要使用 super 来调用,直接即可调用。但如果子类覆盖或重写了父类的方法,则只有使用 super 才能在子类中调用父类中的被重写的方法。

this 关键字表示当前对象。可用于:

    • 调用当前类的构造方法,并且必须是方法的第一条语句。如:this(); 调用默认构造方法。this(参数); 调用带参构造方法。
    • 限定当前对象的数据域变量,一般用于方法内的局部变量与对象的数据域变量同名的情况。如 this.num = num。this.num 表示当前对象的数据域变量 num,而 num 表示方法中的局部变量。
  • final 关键字:声明类可以把类定义为不能继承的,即最终类,格式:final class 类名 {//类体};

或者用于修饰方法,该方法不能被子类重写,格式:

修饰符(public/private/default/protected) final 返回值类型 方法名(){//方法体}

构造器

  • 子类不能继承父类的构造器(构造方法或者构造函数),但是父类的构造器带有参数的,则必须在子类的构造器中显式地通过super关键字调用父类的构造器并配以适当的参数列表。
  • 如果父类有无参构造器,则在子类的构造器中用super调用父类构造器不是必须的,如果没有使用super关键字,系统会自动调用父类的无参构造器。
    class SuperClass {
    private int n;
    SuperClass(){
    System.out.println("SuperClass()");
    }
    SuperClass(int n) {
    System.out.println("SuperClass(int n)");
    this.n = n;
    }
    }
    class SubClass extends SuperClass{
    private int n; SubClass(){
    super();
    System.out.println("SubClass");
    } public SubClass(int n){
    System.out.println("SubClass(int n):"+n);
    this.n = n;
    }
    }
    public class TestSuperSub{
    public static void main (String args[]){
    SubClass sc = new SubClass();
    SubClass sc2 = new SubClass();
    }
    }

    构造器-参数问题 实例


继承注意:

  • java 中若要在子类调用父类的方法,需使用 关键字super。

    class Animal{
    void go(){
    System.out.println("animal go");
    }
    } class Dog extends Animal{
    void go(){
    //调用父类方法
    super.go();
    }
    } //驱动函数
    public static void main(String[] args){
    Dog dog=new Dog();
    dog.go();
    }

    子类调用父类的方法 实例

  • 子类不是父类的子集,子类一般比父类包含更多的数据域和方法。
  • 子类拥有父类非private的属性,方法。
  • 父类中的 private 数据域在子类中是不可见的,因此在子类中不能直接使用它们。
  • 继承是为"是一个"的关系建模的(eg:Shape 类是父类,其子类可以有 Circle 类、Rectangle 类、Triangle 类,等等),父类和其子类间必须存在"是一个"的关系,否则不能用继承。
    但也并不是所有"是一个"的关系都应该用继承。例如,正方形是一个矩形,但不能让 Square 类来继承 Rectangle 类,因为正方形不能从矩形扩展得到任何东西。正确的继承关系是 Square 类继承 Shape 类
  • Java 只允许单一继承(即一个子类只能有一个直接父类),C++ 可以多重继承(即一个子类有多个直接父类)。

Pre-article:Java 学习(10):java 异常处理

Next:Java 学习(12):重写(Override)与重载(Overload) & 多态

Java 学习(11): 面向对象编程—继承(super,this)的更多相关文章

  1. Java学习之==>面向对象编程 Part2

    一.封装 封装,即隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别:将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结 ...

  2. JAVA学习:面向对象编程

    "算法+数据结构=程序"是一句经典名言,这句话很直接的说明了程序的本质:处理数据.产生结果.即便是最简单的HelloWorld程序,我们也可以将字符串"HelloWorl ...

  3. Java学习_面向对象编程

    抽象类 一个class定义了方法,但没有具体执行代码,这个方法就是抽象方法,抽象方法用abstract修饰.因为抽象类本身被设计成只能用于被继承,因此,抽象类可以强迫子类实现其定义的抽象方法,否则编译 ...

  4. Java学习之==>面向对象编程 Part1

    一.面向对象与面向过程 1.面向过程 角度是功能,以方法为最小单位,思考的是具体怎么做. 2.面向对象 角度是抽象,以类为最小单位,思考的是谁来做. 3.示例:“小明去上班” 面向过程 起床,刷牙洗脸 ...

  5. Java学习day7面向对象编程1-对象和类

    一.Java编程中对象和类的概念 1,什么是类? 答:类是客观存在的,抽象的,概念的东西. 2,什么是对象? 答:对象是具体的,实际的,代表一个事物.例如:车是一个类,汽车,自行车就是他的对象. 关于 ...

  6. Java学习day9面向对象编程2-方法的可变个数的参数和方法的参数传递

    一.方法的可变个数的参数. 问题:我们能够打印的信息都是来源于方法的参数,也就是形参的传递.那如何要给方法传递不同的参数? .1.采用数组形参来定义方法 public static void test ...

  7. Java学习day8面向对象编程2-类的属性和方法

    一.类的属性 1.语法格式 修饰符 类型 属性名 = 初值 说明:修饰符private:该属性只能由该类的方法使用.在同一类内可见.使用对象:变量.方法. 注意:不能修饰类(外部类)    修饰符pu ...

  8. C++ Primer 学习笔记_69_面向对象编程 --继承情况下的类作用域

    面向对象编程 --继承情况下的类作用域 引言: 在继承情况下,派生类的作用域嵌套在基类作用域中:假设不能在派生类作用域中确定名字,就在外围基类作用域中查找该名字的定义. 正是这样的类作用域的层次嵌套使 ...

  9. 0028 Java学习笔记-面向对象-Lambda表达式

    匿名内部类与Lambda表达式示例 下面代码来源于:0027 Java学习笔记-面向对象-(非静态.静态.局部.匿名)内部类 package testpack; public class Test1{ ...

  10. Python 面向对象编程 继承 和多态

    Python 面向对象编程 继承 和多态 一:多继承性 对于java我们熟悉的是一个类只能继承一个父类:但是对于C++ 一个子类可以有多个父亲,同样对于 Python一个类也可以有多个父亲 格式: c ...

随机推荐

  1. [Vue warn]: Invalid prop: custom validator check failed for prop "type".

    遇到错误如下, [Vue warn]: Invalid prop: custom validator check failed for prop "type". found in ...

  2. [CodeForces]529B Group Photo 2

    AK爷GhostCai的电脑又蓝屏了Orz 贪心题,确定一个maxh,限定h不大于一个值.枚举maxh. check的时候的细节很多: 1.h>maxh但w<maxh交换的时候需要占用交换 ...

  3. 一、Git起步

    1.关于版本控制 版本控制系统:版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统.但实际上,你可以对任何类型的文件进行版本控制. 1.1 本地版本控制系统 许多人习惯用复制 ...

  4. Linux下pyftplib简单的脚本

    from pyftpdlib.authorizers import DummyAuthorizer from pyftpdlib.handlers import FTPHandler from pyf ...

  5. ElasticSearch启动报错,bootstrap checks failed

    修改elasticsearch.yml配置文件,允许外网访问. vim config/elasticsearch.yml# 增加 network.host: 0.0.0.0 启动失败,检查没有通过,报 ...

  6. java实现随机数的生成

    一,课程中的动手动脑的问题 1,编写一个方法,使用以上算法生成指定数目的随机整数. public void suiJiShu(){ Scanner input=new Scanner(System.i ...

  7. 2015 Multi-University Training Contest 7 hdu 5372 Segment Game

    Segment Game Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tota ...

  8. ASP.NET-SOAP、UDDI知识点

    1. 什么是SOAP? 答:是简单访问协议.是在分布式环境中,交换信息并实现远程调用的协议.是一个基于XML的协议.使用SOAP,可以不考虑任何传输协议,但通常还是HTTP协议,可以允许任何类型的对象 ...

  9. 中科燕园arcgis外包案例之12---供水供热管线GIS系统

    项目背景 绍兴县是浙江省第一个"数字城管"试点城市,也是全国第一个"数字城管"县级城市.随着经济的飞速发展.城市化步伐的加快,以及城市规模的扩大和现代化程度的不 ...

  10. [博弈] hdu 3683 Gomoku

    题意: 两个人下五子棋.给你现有棋盘,推断在三步之内的胜负情况. 输出分为几种. 1.棋盘不合法 2.黑或白在第一步赢下在(x,y)点,多个输出x最小的.y最小的. 3.输在第二步 4.黑或白在第三步 ...