LoginSignup
13
8

More than 3 years have passed since last update.

Javaを使ったオブジェクト指向プログラミング総まとめ

Last updated at Posted at 2019-05-24

Javaを使ったオブジェクト指向プログラミング総まとめ

勉強会に向けて作った資料が、「まぁ自分の割にはそこそこなの作れたのかな」と思ったので、これを期に初投稿。といいつつ、これで間違った内容を書いていたらとてもとても恥ずかしい。

クラスとは

オブジェクト指向では、振る舞い属性を持つ1の単位をオブジェクトと呼び、このオブジェクトの種類をクラスと呼ぶ。もう少し話を砕くと、

  • 振る舞い:ある動作。メソッド
  • 属性:ある情報。フィールド
  • オブジェクト: メソッド+フィールド(つまりメンバ
  • クラス:オブジェクトの種類

である。

クラスの定形構文は以下の通りである。

class sandbox {
  public int field;
  public void method() {
    // Write anything process.
  }
}

基本的なクラスの使い方

インスタンス化

クラスオブジェクトを生成すること。別名「newする」。インスタンス化は以下のように行う。インスタンス化することで、インスタンス化したクラスのメンバやメソッドが使える。

class sandbox {
  public static void main(String[] args) {
    Class cls = new Class(); // Create instance.
    cls.method(); // You can action method() of  Class.
  }
}

class Class {
  public int field;
  public void method() {
    // Write anything process.
  }
}

コンストラクタ

コンストラクタとはインスタンス化された際に一度だけ実行されるメソッド。コンストラクタを生成する際は、メソッド名をクラス名と同じにすれば良い。

class sandbox {
  public static void main(String[] args) {
    Class cls = new Class();
    // Create instance and action constructor.
  }
}

class Class {
  public int field;
  public Class() {
    System.out.println("Action constructor.");
  }
  public void method() {
    // Write anything process.
  }
}

実行結果

Action constructor.

修飾子

1. アクセス修飾子

アクセス修飾子をつけることで、外部からのアクセスを制限することができる。

アクセス修飾子 アクセス可能範囲
public すべて
protected 同一パッケージ内・自クラス・サブクラス
なし 同一パッケージ内・自クラス
private 自クラス

簡単なアクセス例は以下の通り。

class sandbox {
  public static void main(String[] args) {
    Class cls = new Class(); // Create instance.
    System.out.println("You can access " + cls.public_fld + " field.");
    System.out.println("You can access " + cls.protected_fld + " field.");
    System.out.println("You can access " + cls.nothing_fld + " filed.");

    // Compile err.
    // System.out.println("You can " + cls.private_fld + " field.");
  }
}

class Class {
  public String public_fld = "public";
  protected String protected_fld = "protected";
  String nothing_fld = "nothing";
  private String private_fld = "private";
}

実行結果

You can access public field.
You can access protected field.
You can access nothing field.

最後のSystem.out.println("You can " + cls.private_mbr + "member");をコメント解除してコンパイルしようとすると、アクセス制限でコンパイルエラーが起きる。

2. static修飾子

static修飾子をつけると、実行時にメモリ上に展開されてインスタンス化しなくてもアクセスできるようになる。

class sandbox {
  public static void main(String[] args) {
    System.out.println("You can access " + Class.static_fld + " field.");
  }
}

class Class {
  static String static_fld = "static";
}

実行結果

You can access static field.

3. final修飾子

final修飾子を使用することで、定数とし、値の変更ができなくなる。

class sandbox {
  public static void main(String[] args) {
    System.out.println("You can access " + Class.static_fld + "member.");

    // Compile err.
    // Class.static_fld = "final";
  }
}

class Class {
  static final String static_fld = "static";
}

カプセル化

フィールドとメソッドをひとまとめにして、保護したいメンバにprivateをつけてアクセスできないようにすること。カプセル化は基本、

  • 値を取得する:getter
  • 値を代入する:setter

がよく使われている。この2つのメソッドのことはアクセサメソッドと呼ぶ。

class sandbox {
  public static void main(String[] args) {
    Class cls = new Class();
    cls.setField("hoge");
    System.out.println(cls.getField());
  }
}

class Class {
  private String field = "";

  /**
   * Accessor method.
   * setField(String param) -> Setter
   * getField() -> Getter
  **/
  void setField(String param) {
    field = param;
  }

  String getField() {
    return field;
  }
}

実行結果

hoge

しかし、gettersetterを作って、せっかくprivateをつけたフィールドにアクセスできてしまうと意味がないという話もあって、純粋なgettersetterはカプセル化を実現しないと、この記事に書いていた。

ちなみにカプセル化は、データや処理を気にせずに目的を達成できるようにしたものという意味もある(コメントで教えていただき、記事にもしてくれました。)。

発展的なクラスの使い方

継承

クラスに親子関係をもたせること。親クラスを継承した子クラスは、親クラスの機能が受け継がれる

class sandbox {
  public static void main(String[] args) {
    Child cld = new Child();
    cld.sayCommentByPerson();
    cld.sayCommentByChild();
  }
}

// Super class.
class Person {
  void sayCommentByPerson() {
    System.out.println("I am Person.");
  }
}

// Sub class.
class Child extends Person {
  void sayCommentByChild() {
    System.out.println("I am Child.");
  }
}

実行結果

I am Person.
I am Child.

親クラスのコンストラクタを呼ぶには

もし、親にコンストラクタがあり、それを呼びたいときは、super();とすれば良い。

class sandbox {
  public static void main(String[] args) {
    Child cld = new Child();
    cld.sayCommentByChild();
  }
}

// Super class.
class Person {
  Person() {
    System.out.println("I am Person.");
  }
}

// Sub class.
class Child extends Person {

  //Call constructor of super class.
  Child() {
    super();
  }

  void sayCommentByChild() {
    System.out.println("I am Child.");
  }
}

実行結果

I am Person.
I am Child.

オーバーロード

オーバーロードとは異なる引数を持つ同じ名称のメソッドを複数生成すること。

class sandbox {
  public static void main(String[] args) {
    Class strClass = new Class("hoge");
    Class intClass = new Class(1);
  }
}

class Class {
  Class(String param) {
    System.out.println("String: " + param);
  }

  Class(int param) {
    System.out.println("Integer: " + param);
  }
}

実行結果

String: hoge
Integer: 1

オーバーライド

オーバーライドは、親クラスから継承されたメソッドを子クラスで上書きすること。

class sandbox {
  public static void main(String[] args) {
    Child cld = new Child();
    cld.sayComment();
  }
}

// Super class.
class Person {
  void sayComment() {
    System.out.println("I am Person.");
  }
}

// Sub class.
class Child extends Person {

  @Override
  void sayComment() {
    System.out.println("I am Child.");
  }
}

多態性(ポリモーフィズム)

オーバーロードやオーバーライド、インタフェース(後述)によって、用途によって振る舞いを変えることができること。

抽象クラス

親クラスの用途のみを考えたクラス。したがって、直接インスタンス化することはできない。

class sandbox {
  public static void main(String[] args) {
    // Compile err.
    // Person prson = new Person();

    Child chld = new Child();
    chld.sayCommentByPerson();
    chld.sayCommentByChild();
  }
}

abstract class Person {
  void sayCommentByPerson() {
    System.out.println("I am Person.");
  }
}

class Child extends Person {
  void sayCommentByChild() {
    System.out.println("I am Child.");
  }
}

実行結果

I am Person.
I am Child.

インタフェース

抽象クラスをさらに抽象化したもの。インタフェースではメソッドの宣言はできるが、処理は原則書かない。普通に処理を書こうとするとコンパイルエラーが起きる。

class sandbox {
  public static void main(String[] args) {
    Class cls = new Class();
    cls.sayComment();
  }
}

class Class implements Interface {
  public void sayComment() {
    System.out.println("I am Class.");
  }
}

interface Interface {
  void sayComment();
}

また、interface内のメソッドはpublicとして扱われるため、ClassinterfacesayComment()を使うときは、publicを付けなければならない。また、interface内のメンバはpublic static finalとして扱われる。

interface内で処理を記述するとき

default修飾子をつける。

class sandbox {
  public static void main(String[] args) {
    Class cls = new Class();
    cls.sayComment();
  }
}

class Class implements Interface {

}

interface Interface {
  default void sayComment() {
    System.out.println("I am Interface.");
  }
}

実行結果

I am Interface.

クラスは複数のinterfaceを取り込むことができる

class sandbox {
  public static void main(String[] args) {
    Class cls = new Class();
    cls.sayComment1();
    cls.sayComment2();
  }
}

class Class implements Interface1, Interface2 {

}

interface Interface1 {
  default void sayComment1() {
    System.out.println("I am Interface1.");
  }
}

interface Interface2 {
  default void sayComment2() {
    System.out.println("I am Interface2.");
  }
}

実行結果

I am Interface1.
I am Interface2.
13
8
5

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
13
8