java-抽象方法和抽象类(abstract)

一、抽象方法和抽象类

1.抽象方法:在方法前加abstract修饰。只有方法的声明,没有方法的实现。

(1)作用:为子类提供统一接口。

(2)格式:

abstract ReturnType MethodName();

2.抽象类:在类前加abstract修饰。抽象类中可以有抽象方法和非抽象方法。

(1)抽象类不能被实例化,即不能有抽象类的对象。

(2)抽象类的子类仍可以是抽象类。

(3)final和abstract不能同时修饰一个类,因为final不能被继承,abstract类必须被继承。

(4)抽象类的子类必须实现抽象类的所有方法,不然它也要被定义为抽象类。所以类中有抽象方法的类就是抽象类。

二、程序实例:

package com.nine;//: c07:music4:Music4.java
// From 'Thinking in Java, 2nd ed.' by Bruce Eckel
// www.BruceEckel.com. See copyright notice in CopyRight.txt.
// Abstract classes and methods.
import java.util.*;

abstract class Instrument {           //基类
  int i; // storage allocated for each
  public abstract void play();    //play方法抽象
  public String what() {
    return "Instrument";
  }
  public abstract void adjust();   //adjust方法抽象
}

class Wind extends Instrument {        //子类1
  public void play() {
    System.out.println("Wind.play()");
  }
  public String what() { return "Wind"; }
  public void adjust() {}
}

class Percussion extends Instrument {    //子类2
  public void play() {
    System.out.println("Percussion.play()");
  }
  public String what() { return "Percussion"; }
  public void adjust() {}
}

class Stringed extends Instrument {     //子类3
  public void play() {
    System.out.println("Stringed.play()");
  }
  public String what() { return "Stringed"; }
  public void adjust() {}
}
 
class Brass extends Wind {          //wind的子类1
  public void play() {
    System.out.println("Brass.play()");
  }
  public void adjust() { 
    System.out.println("Brass.adjust()");
  }
}

class Woodwind extends Wind {        //wind的子类2
  public void play() {
    System.out.println("Woodwind.play()");
  }
  public String what() { return "Woodwind"; }
}

public class Music4 {
	
  // Doesn't care about type, so new types
  // added to the system still work right:
  static void tune(Instrument i) {
    // ...
    i.play();
  }
  static void tuneAll(Instrument[] e) {
    for(int i = 0; i < e.length; i++)
      tune(e[i]);
  }
  public static void main(String[] args) {
    Instrument[] orchestra = new Instrument[5];
    int i = 0;
    // Upcasting during addition to the array:
    orchestra[i++] = new Wind();
    orchestra[i++] = new Percussion();
    orchestra[i++] = new Stringed();
    orchestra[i++] = new Brass();
    orchestra[i++] = new Woodwind();
    tuneAll(orchestra);
  }
} 

输出为:

Wind.play()
Percussion.play()
Stringed.play()
Brass.play()
Woodwind.play()
通过这个程序再说一下方法调用:

对重载的方法,java虚拟机根据传递给方法的参数个数和类型(即参数列表)确定调用哪个方法;对覆盖的方法,java的运行时系统根据实例类型决定调用哪个方法;对于子类的一个实例,如果子类覆盖了超类的方法,运行时系统执行子类的方法,如果子类继承了超类的方法,则运行时系统执行超类的方法。

讨论一下下面的代码:

 static void tune(Instrument i) {       
    // ...
    i.play();
  }
  static void tuneAll(Instrument[] e) {
    for(int i = 0; i < e.length; i++)
      tune(e[i]);

这里其实体现了抽象的好处,即调用play方法时,系统根据对象的实际类型调用相应的play方法,如果以后再加一个Instrument的子类,程序不用修改。提高了程序的可维护性和可扩展性。

参考资料:
《java语言程序设计》——清华大学出版社

《java编程思想》——机械工业出版社

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值