自分用。
以下javaでかきまーす。
ほんっとに良くないと思うんだけど、まだこれらの構文を使ってないので多分認識違いがあります。
暇なときにコード書いて、動かして、ほほぅ...?ってやるから待ってて。
継承
継承。extendsのこと。
継承されるクラスのことをsuperクラス、親クラスという。
継承したクラスのことを子クラスという。
子クラスはsuperクラスのすべてを持っているので、superクラスの変数、メソッドを使うことができる。
superクラスのprivateアクセス修飾子がついているものは利用できない。
protected修飾子であれば使える。
以下は走る、寝るだけができる謎の生き物のクラス。
子クラスはとりあえず親クラスの関数を呼ぶだけ。
走ったらスタミナが10消費されて、寝たらスタミナが10回復する生き物。
class superClass(){
stamina = 100;
protected void run(){
stamina -= 10;
}
protected void sleep(){
stamina += 10;
}
}
class childClass extends superClass{
public voic main(){
System.out.println(stamina);
// 100(親クラスのstamina変数の値が出る)
run();
sleep();
//親クラスのメソッドを使える
}
}
Override
子クラスで、superクラスなどのメソッドを書き換えたい。
そんなときにするのがOverride。メソッドを上書き定義できる。
さっきの走って寝る謎の生き物をチート級のバグ生物に変えてみよう
走ったらスタミナが5消費されて、寝たらスタミナが50回復する生き物。
class superClass(){
int stamina = 100;
protected void run(){
stamina -= 10;
}
protected void sleep(){
stamina += 10;
}
}
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を使う方法【初心者向け】
インタフェースと抽象クラスどっち使ったらいいんだ?