この章ではインスタンスを生成できないクラスである抽象クラス
についてとりあげます
抽象クラス
Javaの抽象クラスは、クラスの設計図のようなもので、継承して使われるスーパークラスとなることが前提のクラスです
抽象クラスは、共通の処理を持つクラス群をまとめるのに適しています
抽象クラスの特徴
具体的な処理内容が書かれていないメソッド(抽象メソッド) を含んでいることが特徴です
また、次のようなメリットがあります
- 複数のクラスで共通する処理を抽象クラスに記述することで、コードの重複を減らすことができる
- 抽象クラスを継承するクラスは、必ず抽象メソッドをオーバーライドする必要があり、これにより、クラスの設計が統一され、プログラム全体の整合性を保つことができる
- 新しいクラスを追加する際に、抽象クラスを継承することで、既存のコードを変更せずに機能を追加できる
抽象クラスは、共通の処理や属性を持つクラス群をまとめたり、クラスの継承関係を明確にしたい場合に適しています
使い方
以下のようにクラスを宣言する前にabstract
を記述します
また、オーバーライドして使う必要のあるメソッドにもabstract
を記述します
abstractを記述したメソッドを抽象メソッド
といいます
abstract class クラス名{
abstract 戻り値の型 メソッド名(引数の型 仮引数,,,);
}
抽象メソッドは、具体的な内容は記述する必要がありません
継承したサブクラスで実装します
以下は抽象クラスを用いたサンプルプログラムです
abstract class Shape{
int color;
int dot;
public void drawCharacter(){
System.out.println("color=" + this.color + " dot=" + this.dot);
}
abstract void draw();
abstract double calcArea();
}
class Rectangle extends Shape{
double height;
double width;
Rectangle(int color,int dot,double height,double width){
this.color=color;
this.dot=dot;
this.width=width;
this.height=height;
}
public void draw(){
System.out.println("in rectangle");
this.drawCharacter();
}
public double calcArea(){
return this.width * this.height;
}
}
class Circle extends Shape{
double radius;
static double PI=3.14;
Circle(int color,int dot,double radius){
this.color=color;
this.dot=dot;
this.radius=radius;
}
public void draw(){
this.drawCharacter();
System.out.println("in circle");
}
public double calcArea(){
return this.radius*this.radius*PI;
}
}
public class Sample{
public static void main(String []args){
Rectangle rect = new Rectangle(0xff0000,1,1.5,2.0);
Circle circle = new Circle(0x00ff00,1,1.5);
rect.draw();
circle.draw();
double area = rect.calcArea();
System.out.println("rect area=" + area);
area = circle.calcArea();
System.out.println("circle area=" + area);
}
}
実行結果
in rectangle
color=16711680 dot=1
color=65280 dot=1
in circle
rect area=3.0
circle area=7.065
抽象クラスのShapeクラスはクラスの設計図であり、線の色と太さをもち、描画と面積の計算を取得するメソッドを実装することを定義しています
そして、そのサブクラスとしてRectangleクラスとCircleクラスを定義します
Shapeクラスには、抽象メソッドdraw()とcalcArea()が宣言されており、Rectangleクラス、Circleクラスではこれらのメソッドがオーバーライドされています
また、Shapeクラスには、通常のメソッドのdrawCharacter()が宣言されていて、Rectangleクラス、Circleクラスではこのメソッドを呼び出すことができます
【演習問題】
- サンプルグラムを実装してみましょう
- Triangleクラス(三角形)を追加してみましょう
- 次のようなradioクラスとTelevisionクラスがあります。電源状態の処理が共通になるため、抽象クラスのPowerableクラスを作成してみましょう
class Radio{
private int battery; // バッテリー残量
private boolean powerStatus; // 電源状態
public Radio(int battery) {
this.battery = battery;
this.powerStatus = false; // 初期状態はOFF
}
public boolean getPowerStatus() {
return this.powerStatus;
}
public int getBattery() {
return this.battery;
}
public void setBattery(int battery) {
this.battery = battery;
}
public void powerOn() {
if (this.battery > 0) {
// バッテリー残量が0より大きい場合のみ電源ON可能
// 電源ON処理
this.powerStatus = true;
System.out.println("ラジオの電源をONにしました。");
} else {
System.out.println("バッテリー残量がありません。電源をONにできません。");
}
}
public void powerOff() {
// 電源OFF処理
this.powerStatus = false;
System.out.println("ラジオの電源をOFFにしました。");
}
}
class Television{
private boolean powerStatus; // 電源状態
public Television(boolean socket) {
this.powerStatus = false; // 初期状態はOFF
}
public boolean getPowerStatus() {
return this.powerStatus;
}
public void powerOn() {
// 電源ON処理
this.powerStatus = true;
System.out.println("テレビの電源をONにしました。");
}
public void powerOff() {
// 電源OFF処理
this.powerStatus = false;
System.out.println("テレビの電源をOFFにしました。");
}
}
public class Main {
public static void main(String[] args) {
Radio radio = new Radio(50); // バッテリー残量50でラジオを作成
radio.powerOn(); // 電源ONを試みる
radio.powerOff(); // 電源OFF
radio.setBattery(0); // バッテリー残量を0にする
radio.powerOn(); // 電源ONを試みる (バッテリー不足)
Television tv = new Television(); // テレビを作成
tv.powerOn(); // 電源ONを試みる
tv.powerOff(); // 電源OFF
}
}
コメント