LoginSignup
0
0

More than 5 years have passed since last update.

継承と、インターフェースと。

Last updated at Posted at 2018-09-06

自分用。
以下javaでかきまーす。

ほんっとに良くないと思うんだけど、まだこれらの構文を使ってないので多分認識違いがあります。
暇なときにコード書いて、動かして、ほほぅ...?ってやるから待ってて。

継承

継承。extendsのこと。
継承されるクラスのことをsuperクラス、親クラスという。
継承したクラスのことを子クラスという。

子クラスはsuperクラスのすべてを持っているので、superクラスの変数、メソッドを使うことができる。
superクラスのprivateアクセス修飾子がついているものは利用できない。
protected修飾子であれば使える。

以下は走る、寝るだけができる謎の生き物のクラス。
子クラスはとりあえず親クラスの関数を呼ぶだけ。

走ったらスタミナが10消費されて、寝たらスタミナが10回復する生き物。

sperClass.java
class superClass(){
    stamina = 100;

    protected void run(){
        stamina -= 10;
    }

    protected void sleep(){
        stamina += 10;
    }
}
childClass.java
class childClass extends superClass{
    public voic main(){
        System.out.println(stamina);
            // 100(親クラスのstamina変数の値が出る)

        run();
        sleep();
            //親クラスのメソッドを使える
    }
}

Override

子クラスで、superクラスなどのメソッドを書き換えたい。
そんなときにするのがOverride。メソッドを上書き定義できる。

さっきの走って寝る謎の生き物をチート級のバグ生物に変えてみよう
走ったらスタミナが5消費されて、寝たらスタミナが50回復する生き物。

sperClass.java
class superClass(){
    int stamina = 100;

    protected void run(){
        stamina -= 10;
    }

    protected void sleep(){
        stamina += 10;
    }
}
childOverride.java
class childOverride extends superClass{
    @Override
    private void run(){
        stamina -= 5;
    }

    @Override
    private void sleep(){
        stamina += 50;
    }

    public void main(){
        //なんか適当に処理
    }
}

はい。やべぇ生き物ができました。

同名のメソッドを子クラスで再定義することで、子クラスで定義した内容に置き換わる。

@Overrideは下記のメソッドがオーバーライドしようとしているということをコンパイラに明示するためのもので、書かなくても動作上は問題ないのだそう。
ただ、@Overrideをつけておけば、コンパイルする時にsuperクラスに同名のメソッドが存在しなければエラーを出してくれるようになるので、バグを動作させる前に発見できるようになる。

Overrideできるのはメソッドだけで、変数はできない。

superキーワード

superクラスのコンストラクタを動かしたい。Overrideする前のsuperクラスの関数を使いたい。
superクラスの変数を再代入したい。

そんなときに使うのがsuperキーワード。

子クラスのインスタンスが生成される時、勝手にsuperクラスのインスタンスも生成されるが、そのsuperクラスのコンストラクタに引数を渡したい時なんかに有用。

super(param, args);

という感じで呼べば、コンストラクタへ引数を渡すことができる。
いつでもsuperクラスのコンストラクタを呼べるけど、子クラスのコンストラクタから以外では非推奨なのでやらないほうがいい。

インターフェース

インターフェースは設計図のようなものだと思うのが良さそう。
「こういう機能を用意してください」と明示しておくためのものである。

public interface actions{
    void run();
    void sleep();
    void eat();
    void jump();

で、コレに従ってimplementsをするクラスを書いていく。

class Hito implements antions{
    @Override
    public void run(){
        //2本足で全力疾走
    }

    @Override
    public void sleep(){
        //布団敷いて寝る
    }

    @Override
    public void eat(){
        //スプーンとフォークを使って食べる
    }

    ...

}

コレは人。2本の足で全力疾走できますよね。

class Dog implements antions{
    @Override
    public void run(){
        //4本足で全力疾走
    }

    @Override
    public void sleep(){
        //お気に入りの場所で丸くなって寝る
    }

    @Override
    public void eat(){
        //口で直接皿にいく
    }

    ...

}

こっちは犬。4本の足で走り、とぐろを巻いて寝て、口のみを使って食事をするはずです。一般的な犬であれば。

こういう感じで、設計と実装を分けて書くのがインターフェース。implementsは「実装」っていう意味なんですって。
クラスを作るときのテンプレート的な?感じがする。

抽象クラス(abstruct)

前述のinterfaceみたいな感じで、継承を必ず必要とするクラスを抽象クラスという。
abstruct修飾子をクラスにつけると直接のインスタンス生成ができなくなり、メソッドにつければそのメソッドをそのまま呼び出すことはできなくなる。
abstruct修飾子がついたメソッドを含むクラスは必ずabstruct修飾子をつける必要がある。

未完成のメソッドを持つクラスのインスタンスなんか作っちゃだめだよねってこと。

public abstruct class action{
    int O2;
    void Kokyu(){
        O2 += 10;
    }

    abstruct void run();
    abstruct void sleep();
    abstruct void eat();
}
class Hito extends action{
    @Override
    void run(){
        //走る
    }

    @Override
    void sleep(){
        //布団敷いて寝る
    }

    ...

    public void main(){
        Kokyu();
            //呼吸する(superクラスのメソッド)

        run()
            //走る

        sleep();
            //寝る
    }
}

えっ...?

うんうん。わかるよ...
実質interfaceやんけって言いたくなるよね。わかるわかる。

interfaceの場合は、複数のinterfaceに対して、ひとつのクラスがいっぱいimplementsできる。
でも継承は、ひとつのクラスがいっぱい継承することができない。

interfaceの変数は勝手にstatic final修飾子がつき、定数になってしまうので再代入ができなくなる。
また、interfaceに書かれるメソッドは全部abstructみたいなもんで、処理はかけない。

抽象クラスはあくまでもベースはクラスなので、abstructじゃないメソッドも書けるし、変数も持てる。
一部未完成のクラスだから、ちゃんと完成させてから使ってね、という雰囲気。

設計図未完成のクラス
そういう違いがある。

余談 : is-aとhas-a

is-a

is-a は A is a B 。
AはBであるという考え方。

Aはどっちかって言うとBっぽい。Bがベースにあるっぽい。
また別のCもBっぽい。Bがベースにあるっぽい。

だったらAもCも、Bを元に作れるよね。っていうこと(だと思う)

has-a

has-a は A has a B 。
AはBを持っているという考え方。

AはBっぽいものを持ってる。また別のCもBっぽいものを持っている。
だったらこのBっぽいものを共通化できるようにしちゃおう。ってこと(だと思う)

参考

【Java】オーバーライドって何?
インターフェースを実装!Javaでimplementsを使う方法【初心者向け】
インタフェースと抽象クラスどっち使ったらいいんだ?

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0