编程

Java继承和多态

2018-02-22  本文已影响61人  Golden30

Java继承和多态

继承

定义

继承就是利用现有类创建新类的过程,现有的类称为 父类(基类),新类称为 子类(派生类)。比如现实中:儿子继承了父亲遗产一样。面向对象程序设计中的继承,就是代码重用。
Java中所有的类都继承自 Object 这个父类。

实现

在Java中实现继承需要使用到extends关键字;

[访问修饰符] class 派生类名 extends 基类名 {
        成员列表
    }

如:

class Student extends Person
{
    ……
}

访问修饰符 请参看之前章节的内容。

例子

例:

定义抽象类:Person。

public abstract class Person {  // 抽象类
    private String name;  // 私有变量
    
    public String getName() {  // Getter方法
        return name;
    }
    public void setName(String name) {  //Setter方法
        this.name = name;
    }
        
    public Person(String name) {  // 构造函数,用于初始化name
        super();
        this.name = name;
    }
    public abstract String getDesc();  // 抽象类中的抽象方法。  只有声明,没有具体实现。
  
      public String toString(){      // toString方法覆盖了Object类的toString方法
         return name + getDesc();
      }
}

public class Student extends Person {  // 继承类
    private String major; // 新增加的数据    
    
    public String getMajor() {
        return major;
    }
    
    public void setMajor(String major) {
        this.major = major;
    }    
    
    public Student(String name,String major) { // 构造函数用于初始化
        super(name);   // 调用超类构造函数
        this.major = major;
    }
    
    @Override
    public String getDesc() {  // 必须实现超类中的抽象方法
        // TODO Auto-generated method stub
        return " : a student, major is " + major;
    }

继承的作用

注意事项

继承中的构造方法

class ParentClass {  //定义父类
  public ParentClass() {  //构造方法
    System.out.println("这是父类的构造方法。");
  }
}

class ChildClass extends ParentClass {  //子类继承于父类
  public ChildClass() {  //构造方法
    System.out.println("这是子类的构造方法。");
  }
}

public class ConstructorTest {  //该类用于容纳main方法
  public static void main(String[] args) {
    ChildClass cc = new ChildClass();  //实例化子类对象
  }
}

super

如果子类需要调用父类的方法或者属性怎么办?

如:

class Point  //定义"点"类
{
  protected float mX, mY;  //x轴坐标和y轴坐标

  public Point(float x, float y)  //构造方法
  {
    mX = x;
    mY = y;
  }
  ……
}

class Circle extends Point  //定义"圆"类继承于"点"类
{
  protected float mRadius;    //半径

  public Circle(float x, float y, float r)  //构造方法
  {
    super(x, y);  //显式调用父类构造方法,必须是第一条语句
    mRadius = r;
  }
  ……
}

多态

方法覆盖

定义

如:

/*如果不但名称相同,而且连方法原型也完全相同的话,则构成方法覆盖*/
class ParentClass {  //定义父类
  public void fun() {
    System.out.println("这是父类中的方法。");
  }
}

class ChildClass extends ParentClass {//子类继承于父类
  public void fun() {  //子类覆盖父类中的方法
    System.out.println("这是子类中的方法。");
  }
}

class OverriddenTest {  //用于容纳main方法
  public static void main(String[] args) {
    ParentClass parObj = new ParentClass();
    parObj.fun();  //父类的实例调用此方法

    ChildClass chiObj = new ChildClass();
    chiObj.fun();  //子类的实例调用此方法
  }
}
方法覆盖的注意事项

引用转型

如:

BaseClass obj = new DerivedClass();

如:

class Shapes {  //基本形状类
  public void draw() {  //绘图的方法
    System.out.println("绘制了一个基本形状。");
  }
}
class Circle extends Shapes {  //圆形类继承于基本形状类
  public void draw() {  //覆盖父类的绘图方法
    System.out.println("绘制了一个圆形。");
  }
} 
class Square extends Shapes {  //正方形类继承与基本形状类
  public void draw() {  //覆盖父类的绘图方法
    System.out.println("绘制了一个正方形。");
  }
}
public class polymorphismDemo {
  public static void main(String[] args) {
    Shapes obj = new Shapes();  //父类的引用指向父类的实例
    obj.draw();                 //调用绘图方法
    obj = new Circle();         //父类的引用指向子类的实例
    obj.draw();                 //调用绘图方法
    obj = new Square();         //父类的引用指向子类的实例
    obj.draw();                 //调用绘图方法
  }
}

多态

在Java中,使用父类的引用,调用同一个方法,却可以得到不同的调用结果,这就是多态。即: 同一函数,多种形态。
实际上多态包括 动态多态静态多态

静态多态
动态多态

动态多态也称为运行时多态,即在运行时才能确定调用哪个方法。
形成动态多态必须具体以下条件:

由上述条件可以看出,继承是实现动态多态的首要前提。

抽象

抽象方法

基类无法(或者没有必要)提供被覆盖方法的具体实现,那么就可以将这个方法定义为 抽象方法

[访问权限] abstract 返回值类型 方法名(参数列表){
}

如:

public abstract void draw(){
}
抽象类

如果某个类包含抽象方法,那么这个类就必须定义成 抽象类

[访问权限] abstract class 类名{
    成员列表
}

如:

public abstract class Shapes{
    public abstract void draw();
}
抽象类的注意事项

如:

abstract class Shapes {  //基本形状类,抽象类
    public abstract void draw();  //绘图方法,抽象方法
}
class Circle extends Shapes {  //圆形类继承于基本形状类
    public void draw() {  //实现抽象父类的抽象绘图方法
        System.out.println("绘制了一个圆形。");
    }
}
class Square extends Shapes {  //正方形类继承与基本形状类
    public void draw() {  //实现抽象父类的抽象绘图方法
        System.out.println("绘制了一个正方形。");
    }
}
public class abstractDemo {  //该类用于容纳main方法
    public static void main(String[] args) {
        Shapes obj;
        obj = new Circle();         //父类的引用指向子类的实例
        obj.draw();                 //调用绘图方法
        obj = new Square();         //父类的引用指向子类的实例
        obj.draw();                 //调用绘图方法
    }
}

接口

接口定义

如果某个类中所有的方法都是 抽象方法,那么可以考虑将该类定义为接口。

[访问权限] interface 接口名{
    成员列表
}

如:

public interface IMyInterface{
    public void doIt();
}
实现接口

接口只能用于实现,不能实例化(new)

[访问权限] class 类名 implements 接口名 {
    成员列表
}

如:

public class MyClass implements IMyInterface {
    public void doIt(){
    }
}
接口的注意事项

如:

public interface 子接口名 extends 父接口名 {
    成员列表
}

final关键字

final修饰变量

如果将某个变量修饰为final,那么该变量就成为 常量
如:

final double PI = 3.14159;

☆ 常量在声明时必须初始化。

final修饰方法

如果将某个成员方法修饰为final,则意味着该方法 不能被子类覆盖
如:

public final void fun() {
    ……
}
//如果在派生类中出现同原型的方法,将会报错。
final修饰类

如果将某个类修饰为final,则说明该类 无法被继承
如:

public final class MyClass {
    ……
}
//任何类想继承于MyClass类都将报错。

类和类之间的关系

上一篇下一篇

猜你喜欢

热点阅读