継承とは
既存のクラスを元に変数やメソッドなどの新しい処理や機能を追加したクラスを作る事。
継承関係にある親のクラス(既存のクラス)をスーパークラス、子のクラス(既存のクラスを元に変数やメソッドを追加したクラス)をサブクラスと呼ぶ。
上の写真ではPersonクラスがスーパークラス、SutudentとTeacherクラスがサブクラスになる。
Personクラスでは名前などを扱う変数やメソッドを定義しているとする(斜線の部分が変数やメソッドのイメージ)。Personクラスから継承を行うことでサブクラスであるSutudentとTeacherクラスでPersonクラスが持っている変数やメソッドが使える様になり、さらにSutudentとTeacherクラス独自の変数やメソッドを追加したりする事が出来るようになる。
継承するにはextendsというキーワードを使う。
class サブクラス extends スーパークラス{
:
}
//例文
class Student extends Person{
:
}
継承をすることでコーティング、メンテナンスが楽になる。
継承できるクラスは一つだけ(extendsキーワードの後に書けるスーパークラスは一つだけ)。
コンストラクタは継承しない(コンストラクタの名前はクラス名と合わせるから)(superキーワードを用いることでサブクラスでスーパークラス内のコンストラクタを呼び出して利用する方法がある)。
例文1
public class StuSample{
public static void main(String[] args){
Student stu = new Student();
//スーパークラスのメソッド
stu.setName("菅原");
stu.display();
//サブクラスのメソッド
stu.setStuNo(1);
stu.displayStuNo();
}
}
public class Person{
private String name;
public void setName(String n){
name = n;
}
public void display(){
System.out.println("名前:" + name);
}
}
public class Student extends Person{
private int stuNo;
public void setStuNo(int s){
stuNo = s;
}
public void displayStuNo(){
System.out.println("学席番号:" + stuNo);
}
}
名前:菅原
学席番号:1
実行用クラスの3行目でサブクラスであるStudentクラスのオブジェクトstuを作っている。
StudentクラスはPersonクラスから変数やメソッドを継承しているので6、7行目の様にPersonクラスの変数とメソッドが使える。
オーバーライドとは
サブクラスでスーパークラスのメソッドを再定義(メソッドを上書き)する事。
オーバーライドするには戻り値の型、メソッド名、引数の型と数を全て同じにしないといけない。
*似たような名前のオーバーロードがあるがオーバーロードは一つのクラスの中でメソッドを複数定義する事。
例文2
public class StuSample2{
public static void main(String[] args){
Student2 stu = new Student2();
stu.setName("菅原");
stu.setStuNo(1);
stu.display();
}
}
public class Person2{
private String name;
public void setName(String n){
name = n;
}
public String getName(){
return name;
}
public void display(){
System.out.println("名前:" + name);
}
}
public class Student2 extends Person2{
private int stuNo;
public void setStuNo(int s){
stuNo = s;
}
public void display(){
System.out.println("名前:" + getName());
System.out.println("学籍番号:" + stuNo);
}
}
名前:菅原
学籍番号:1
スーパークラスとサブクラスの両方にdisplayメソッドがあるがオーバーライド(上書き)されているのでサブクラスのdisplayメソッドが表示される。
superでスーパークラスのメソッドを呼び出す
superキーワードを使うと、スーパークラスの変数、メソッドをサブクラスから実行できる。
superを使うことで同じコードを書かなくて済むようになる。
super の後ろにドット(.)をつけて記述する。
super.メソッド名(引数)
superとthisの書き分けや使いどころ
this は「自分自身」、super は「親」を指す。
thisとsuper はそれぞれが持つフィールドやメソッド、コンストラクタへアクセスするために「自分自身」なのか「親」なのかを特定する方法として使われる。
this.~ = 自分のクラスのオブジェクトの変数、メソッドの呼び出し
super.~ = スーパークラスの変数、メソッドの呼び出し
// 実行用クラス
class Main {
public static void main(String[] args) {
Student stu = new Student();
stu.name = "田仲";
stu.stuNo = 12;
stu.display();
}
}
//スーパークラス
class Person{
String name;
void setName(String name){
this.name = name;
// 右辺が引数のname、左辺が変数のname
}
void display(){
System.out.println(this.name);
}
}
//サブクラス
class Student extends Person{
int stuNo;
void display(){
super.display();
System.out.println(stuNo);
}
}
田仲
12
thisキーワード
スーパークラス内にnameという同じ名前で変数と引数が定義されてしまっているの区別がつかなくなってしまうがthisキーワードをつける事で区別をつける事が出来る。
this.name = name;
// 右辺が引数のname、左辺が変数のname
この様にthisキーワードをつける事をつける事で引数の名前を変数の名前と合わせる書き方が出来、引数の名前をわざわざ考えなくて済む。
superキーワード
スーパークラスに書かれたdisplayメソッドをサブクラスでオーバーライドしている。
void display(){
super.display();
System.out.println(stuNo);
}
super.display();と記述することでスーパークラスのdisplayメソッドを(上書きされていないdisplayメソッドを)呼び出している。
この様にsuperキーワードを用いて書くことでサブクラスで新しく変数nameを出力するメソッドを書かなくて良くなり、修正したい場合はスーパークラスのdisplayメソッドを修正するだけで済む。
superとthisによるコンストラクタの呼び出し
コンストラクタは継承されないがsuper、thisの後ろに()を書くことでコンストラクタを呼び出すことが出来る。
クラスの中にいくつかコンストラクタを書きたい、そのコンストラクタの中で似たような処理をさせたい時に使い、同じ処理を何回も書かなくて済むようになる。
this(引数) ←同じクラスの中でコンストラクタを呼び出せる
super(引数) ←スーパークラスの中でコンストラクタを呼び出せる
// スーパークラス
class Person{
String name;
Person(){
this("未設定");
}
Person(String name){
this.name = name;
}
}
// サブクラス
class Student extends Person{
int stuNo;
:
Student(String name, int stuNo){
super(name);
this.stuNo = stuNo;
}
}
thisによるコンストラクタの呼び出し
スーパークラス内で引数なしのコンストラクタPersonと引数ありのコンストラクタPersonが定義されている。
引数なし側のコンストラクタPerson内でthis("未設定");と記述することで引数あり側のコンストラクタPersonを呼び出し、"未設定"という文字列がthis.nameに代入される。
superによるコンストラクタの呼び出し
サブクラス内では引数を二つ持ったコンストラクタStudentが定義されている。
super(name);と記述する事でスーパークラスの引数nameを一つ持ったコンストラクタが呼び出されて(スーパークラスに記述されたPerson(String name)が呼び出される)文字列が代入される。
this.stuNo = stuNo;でサブクラス内(自分のクラス内)の数字が代入される。
✳︎this()、super()を記述する際はコンストラクタ内の先頭に記述する。 (なければ自動的にsuper();が挿入される。)
例文3
public class StuSample3{
public static void main(String[] args){
Student3 stu = new Student3("菅原");
stu.display();
}
}
public class Person3{
private String name;
public Person3(String name){
this.name = name;
}
public void display(){
System.out.println("名前:" + name);
}
}
public class Student3 extends Person3{
private int stuNo;
public Student3(String name){
this(name, 999);
}
public Student3(String name, int stuNo){
super(name);
this.stuNo = stuNo;
}
public void display(){
super.display();
System.out.println("学籍番号" + stuNo);
}
}
参考記事