【独学】はじめてのAndroidプログラミング – 4.7 Java言語の基礎(クラスとオブジェクト)

クラスはオブジェクトの設計図となるプログラムです。クラスを元にしてオブジェクトを生成することをオブジェクト化またはインスタンス化と呼び、そのとき生成されたものをオブジェクトまたはインスタンスと呼びます。どちらの意味も同じですが、本カリキュラムでは今後オブジェクト化とオブジェクトを使用していきます。

Java 言語や Java API で予め定義されているクラスを使うだけでなく、開発者がクラスを自由に定義できます。 クラスの宣言は、次のように「class」予約語の後にクラス名を記述し、「{」から「}」ブレースで囲まれた中にクラスのメンバーとしてフィールドやメソッドを記述します。

通常、public のクラスは、対応するパスのファイルに記述します。例えば、クラス「com.example.SampleClass」は、フォルダ「com/example」の配下のファイル「SampleClass.java」に記述します。またクラス名とファイル名は同じになります。

カリキュラムのサンプル コードは、「Javaコードの実行」に示す手順で実行して確認できます。また「Javaクラス用のファイル作成」でJavaクラス用のファイルを作成できます。このカリキュラムでは、「Example.java」と「Example1.java」を作成します。

クラス修飾子

クラス宣言の前に修飾子を付けて、クラスに属性を付与できます。

  • public:アクセス修飾子。 public のクラスはどこからでもアクセスできる。 public が付けられていないクラスはprivateであり、そのクラスが属するパッケージ内からのみアクセス可能
  • abstract:abstract が付けられたクラスは抽象クラスとなり、抽象クラスはオブジェクト化できない。 抽象クラスに抽象メソッドを持たせて、抽象メソッドの実装をサブクラスで実装する

次に示すクラス「SampleClass」はクラス修飾子が「public」となっているので、どこからでもクラス「SampleClass」をアクセスできます。

public class SampleClass {
    // ここにクラスのメンバーなどを記述
}

次に示すクラス「SampleClass」はクラス修飾子が付与されていないので、そのクラスが属するパッケージ内からのみ、クラス「SampleClass」をアクセスできます。

class SampleClass {
    // ここにクラスのメンバーなどを記述
}

次に示すクラス「SampleAbsClass」はクラス修飾子が「abstract」となっているので抽象クラスになります。抽象クラスに抽象メソッド「sampleMethod」を持たせて、抽象メソッド「sampleMethod」の実装をサブクラスで実装します。

abstract class SampleAbsClass {
    // ここにクラスのメンバーなどを記述
    abstract public void sampleMethod();
}

アクセス制御

クラス自体やフィールドやメソッドのようなクラスのメンバーが、どこからアクセス可能かを表すための修飾子として、次に示すアクセス修飾子があります。

  • private:この修飾子が付けられたメンバーは、そのクラス内部からのみアクセス可能
  • 修飾子無し:特にアクセス修飾子が付けられていない場合、そのクラスが属するパッケージ内の他のクラスからアクセス可能
  • protected:この修飾子が付けられたメンバーは、そのクラス自身とそのクラスのサブクラス、そして、そのクラスが属するパッケージ内の他のクラスからアクセス可能
  • public:この修飾子が付けられたクラスやメンバーは、すべてのクラスからアクセス可能

アクセス修飾子を付与する際の目的は、「要件を満たす範囲でできるだけ狭いアクセス範囲を指定する」ことになります。これによりJavaコードを修正する際にも互換性の維持など調査する範囲を限定できます。

コンストラクタとオブジェクト化

new演算子でオブジェクト化したタイミングで実行されます。次のJavaコードは、クラス「Example」をnew演算子を用いてオブジェクト化します。

Example.java

package com.example.myapplication;

public class Example {
  // ...
}

MainActivity.java

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

// import 文があればここに書く

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // ここにサンプルコードの文を入れる
        Example example = new Example();
    }
}

初期化処理のためにコンストラクタを宣言できます。コンストラクタを用いると、new演算子によりオブジェクトへの参照の戻り値が返される前に変数等の初期化処理が可能となります。

コンストラクタはそのクラスと同じ名前を持ちます。引数をとらないコンストラクタを次に示します。次のjavaコードでは、引数を取らないコンストラクタ「Example」を示します。

public class Example {
 
    Example() {   // 引数を取らないコンストラクタ
        // 変数等の初期化処理など
    }
}

コンストラクタには引数でデータを渡すことができ、異なる引数を取る複数のコンストラクタを宣言できます。次のjavaコードでは、int型の引数を取るコンストラクタ「Example」ではint型変数「count」に引数「aCount」の値を保存し、char型の引数「aMoji」を取るコンストラクタ「Example」ではchar型変数「moji」に引数の値を保存します。

Example.java

package com.example.myapplication;

public class Example {
    int count;
    char moji;

    Example(int aCount) {// int型の引数を取るコンストラクタ
        count = aCount;    // 引数として渡された値をインスタンス変数「count」に代入
    }
    Example(char aMoji) {// char型の引数を取るコンストラクタ
        moji = aMoji;    // 引数として渡された値をインスタンス変数「moji」に代入
    }
}

MainActivity.java

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

// import 文があればここに書く

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // ここにサンプルコードの文を入れる
        Example example = new Example(5);
        System.out.println(example.count); ;  // 5

        Example example_c = new Example('K');
        System.out.println(example_c.moji); ;  // K
    }
}

また、コンストラクタの中から、別のコンストラクタの呼び出すこともできます。コンストラクタの中からの呼び出し方は、クラス名ではなくthis()を使います。これを活用すると、一つのコンストラクタでの処理を他からも使え、効率的なプログラミングができます。次のjavaコードでは、コンストラクタ①を呼び出すとコンストラクタ①からコンストラクタ②が呼び出され、int型変数「count」に引数「aCount」の値が保存されます。

Example.java

package com.example.myapplication;

public class Example {
    int count;
    
    Example() {            // コンストラクタ①
        this(0);  
    }
    Example(int aCount) {  // コンストラクタ②
         count = aCount; 
    }
 }

MainActivity.java

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

// import 文があればここに書く

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // ここにサンプルコードの文を入れる
        Example example = new Example(20);
        System.out.println(example.count); ;  // 20
   }
}

コンストラクタが1つも宣言されていない場合は、何もしない引数なしのコンストラクタ (=デフォルトコンストラクタ) が自動的に作成されます。

メソッド

メソッド宣言は、次のように修飾子、戻り値のデータ型、メソッド名、引数からなります。 修飾子は付けない場合もあり、引数がない場合あるいは引数が複数個宣言される場合があります。

[修飾子] 戻り値のデータ型 メソッド名(引数1, 引数2, ....){

      ・・・
}

次のJavaコードにように、int型の引数をとり戻り値のデータ型がvoidの場合は、return文で戻り値を返しません。「メソッド ‘println(void)’ を解決できません」とエラーメッセージが表示されます。

package com.example.myapplication;

public class Example {
    public void exMethod(int i) {
        return; // 戻り値のデータ型がvoidの場合はreturnで何も返さない
    } 
}

MainActivity.java

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

// import 文があればここに書く

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // ここにサンプルコードの文を入れる
        Example example = new Example();
        System.out.println(example.exMethod(5));
   }
}

次のJavaコードにように、引数をとらずに戻り値のデータ型がint型の場合は、return文でint型の戻り値を返します(この場合「0」)。

Example.java

package com.example.myapplication;

public class Example {
    public int exMethod() {   // 引数をとらずに int型の値を返すメソッド
        return 12; // int型の値を返す
    }
}

MainActivity.java

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

// import 文があればここに書く

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // ここにサンプルコードの文を入れる
        Example example = new Example();
        System.out.println(example.exMethod());  // 12
   }
}

メソッド呼び出しは、クラス内部からの呼び出しには、単にメソッド名に続けて括弧を付けたメソッド呼び出します。 クラス外部からの呼び出しには、「.」(ドット)演算子を使用してどのクラスのどのメソッドを呼び出すかを指定します。

次のJavaコードでは、 コメント「#①」はクラス内部からのメソッドの参照を示します。privateなメソッド「method」をクラス内部から参照しています。 またコメント「#②」はクラス外部からのメソッドの参照を示します。クラス「Example」のpublicなメソッド「exMethod」を、クラス「Example」をオブジェクト化した「example」を使って外部から参照しています。

Example.java

package com.example.myapplication;

public class Example {
    void method() {
        System.out.println("ABC");
    }

    public void exMethod() {
        method();  // #① クラス内部からの参照の場合、特にクラス名などを前に付けなくてよい
    }
}

Example1.java

package com.example.myapplication;

public class Example1 {
    void exMethod1() {
        Example example = new Example();
        example.exMethod();   // #② 外部からの参照
    }
}

MainActivity.java

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

// import 文があればここに書く

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // ここにサンプルコードの文を入れる
        Example example = new Example();
        example.exMethod();      // ABC

        Example1 example1 = new Example1();
        example1.exMethod1();   // ABC
   }
}

メソッドに付ける修飾子を次に示します。

  • アクセス修飾子:public のメソッドはどこからでもアクセス可能。 privateのメソッドはそのクラス内部からのみアクセス可能
  • abstract:メソッド本体なしのメソッド宣言。メソッド本体はサブクラスで実装する必要がある
  • static:クラスメソッドを示す

インスタンスメンバーとクラスメンバー

クラス内にはフィールド、メソッド、コンストラクタといったメンバーを記述できます。その中のフィールドとメソッドについては、オブジェクトに対して関連付けられる「インスタンスメンバー」と、クラスに対して関連付けられる「クラスメンバー」の2種類に分類できます。

インスタンスメンバ ーとしては次のものがあります。次のjavaコードではインスタンス変数として「str」「i」が定義され、インスタンスメソッドとして「exMethod」が定義されています。

  • フィールド:static修飾子が付かない変数
  • メソッド:static修飾子が付かない実行可能なコード

Example.java

package com.example.myapplication;

public class Example {
    private String str = "123";    // インスタンス変数
    private int i = 5;              // インスタンス変数

    void exMethod() {
        System.out.println(i);   // インスタンスメソッド
    }
}

作成したクラス「Example」をオブジェクト化してメソッド「exMethod」を実行すると、インスタンス変数「i」に設定された「5」が表示されます。

MainActivity.java

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

// import 文があればここに書く

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // ここにサンプルコードの文を入れる
        Example example = new Example();
        example.exMethod();
        // 5
    }
}

クラスメンバーとしては次のものがあります。「static」修飾子が付いたクラスメンバーはオブジェクトを生成しないでメンバーにアクセスできます。次のjavaコードでは static 変数として「k」が定義され、 static メソッドとして「showData」が定義されています。

  • フィールド:static修飾子が付いた変数(= static変数)
  • メソッド:static修飾子が付いた実行可能なコード(= staticメソッド)

Example.java

package com.example.myapplication;

public class Example {
    public static int k = 1;   // static変数

    public static void showData() {
        System.out.println(k);   // staticメソッド
    }
}

作成したクラス「Example」のstaticメソッド「showData」を実行すると、static変数「k」に設定された「1」が表示されます。

MainActivity.java

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

// import 文があればここに書く

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // ここにサンプルコードの文を入れる
        Example.showData();
        // 1
    }
}

フィールド

クラスメンバーやインスタンスメンバーに属する変数「フィールド」は、クラス宣言の中に、型と識別子を記述して宣言します。 また同時に、宣言時に初期化もできます。

クラス修飾子のように、フィールドに修飾子を付けることもできます。フィールドの修飾子としては次のものがあります。次のJavaのコードでは、変数「i」はpublic、変数「c」はprivateでクラス変数、変数「MAX_VALUE」はfinalとなります。

  • アクセス修飾子:public のフィールドはどこからでもアクセス可能。 privateのフィールドはそのクラス内部からのみアクセス可能
  • static:クラス変数であることを示す
  • final:初期化された後に変更できないことを表す。  

Example.java

package com.example.myapplication;

public class Example {
    public int i = 4;               // publicな修飾されたint型のフィールド
    private static char c = 0;  // char型の privateな static フィールド. 0 で初期化
    final int MAX_VALUE = 200;  // 値が変えられないので、定数となる
    protected int protect_i = 15;  // 値が変えられないので、定数となる
}

変数「i」、「MAX_VALUE」、「protect_i」はクラス「Example」の外からアクセスでき、それぞれ設定された「4」、「200」、「15」が表示されます。変数「c」はprivate定義されているため、アクセスはできません。

MainActivity.java

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

// import 文があればここに書く

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // ここにサンプルコードの文を入れる
        Example example = new Example();

        System.out.println(example.i);         // 4
        System.out.println(example.MAX_VALUE); // 200
        System.out.println(example.protect_i); // 15
    }
}

フィールドの参照は、クラス内部からであればフィールド名のみで参照できます。 クラス外部からであれば「.」(ドット)演算子を使用してどのクラスを参照するのかを指定します。

次のJavaコードでは、 コメント「#①」はクラス内部の参照を示します。privateなクラス変数「pi」をクラス内部から参照しています。

Example.java

package com.example.myapplication;

public class Example {
    public int i = 45;               // publicな修飾されたint型のフィールド
    private static int pi = 60;  // char型の privateな static フィールド. 0 で初期化
    final int MAX_VALUE = 200;  // 値が変えられないので、定数となる

    void exMethod() {
        System.out.println(pi);  // #① クラス内部からの参照の場合、特にクラス名などを前に付けなくてよい
    }
}

MainActivity.java

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

// import 文があればここに書く

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // ここにサンプルコードの文を入れる
        Example example = new Example();
        example.exMethod();  // 60
    }
}

次のJavaコードでは、コメント「#②」はクラス外部の参照を示します。publicな変数「i」を、クラス「Example」をオブジェクト化した「example」を使って外部から参照して、値を変数「i1」に保存しています。

Example1.java

package com.example.myapplication;

public class Example1 {
    public int i1;               // publicな修飾されたint型のフィールド

    void exMethod1() {
        Example example = new Example();
        i1 = example.i;   // #② 外部からの参照
    }
}

MainActivity.java

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

// import 文があればここに書く

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // ここにサンプルコードの文を入れる
        Example1 example1 = new Example1();
        example1.exMethod1();
        System.out.println(example1.i1);  // 45
    }
}

protectedのサンプルコードを次に示します。protectedは、同じパッケージ内であれば自由にアクセスできます。このサンプルコードを実行すると「100」と表示されます。

Example.java

package com.example.myapplication;

public class Example  {
    protected int field;

    protected void method() {
        System.out.println(field);
    }
}

Example1.java


MainActivity.java

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

// import 文があればここに書く

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // ここにサンプルコードの文を入れる
        Example example = new Example();
        example.field = 100;
        example.method();         // 100
    }
}

また、protectedが付けられたメンバーは、クラス自身とそのクラスのサブクラスからアクセスできます。次のサンプルコードを実行すると「200」と表示されます。

Example.java

package com.example.myapplication;

public class Example  {
    protected int field;

    protected void method() {
        System.out.println(field);
    }
}

Example1.java

package com.example.myapplication;

class Example1 extends Example {
    public void testMethod() {
        field = 200;
        method();
    }
}

MainActivity.java

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

// import 文があればここに書く

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // ここにサンプルコードの文を入れる
        Example1 c = new Example1();
        c.testMethod();          // 200
    }
}

this参照

コンストラクタやメソッドの中では、オブジェクト自身の参照を表すためのthis参照が使用できます。Javaでは必ずしもthisを使用する必要ありませんが、オブジェクト自身を明示的に指し示し、そのフィールドやメソッドを使いたい時に使用します。

例えば次のようにコンストラクタでの例として、コンストラクタ「Example」のパラメータで「i」が渡されたときに、オブジェクト自身の参照を表すthis参照を用いて、publicなint型変数「count」に保存します。

Example.java

package com.example.myapplication;

public class Example  {
    public  int count;

    Example (int i) {
        this.count = i;
    }
}

Example1.java


MainActivity.java

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

// import 文があればここに書く

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // ここにサンプルコードの文を入れる
        Example example = new Example(35);

        System.out.println(example.count);         // 35
    }
}

またメソッドでの例として、publicなメソッド「exMethod」のパラメータで「k」が渡されたときに、オブジェクト自身の参照を表すthis参照を用いて、publicなint型変数「count」に保存します。

Example.java

package com.example.myapplication;

public class Example  {
    public int count;

    public void exMethod (int k) {
        this.count = k;
    }
}

MainActivity.java

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

// import 文があればここに書く

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // ここにサンプルコードの文を入れる
        Example example = new Example();
        example.exMethod(42);
        System.out.println(example.count);         // 42
    }
}

本節の説明は以上になります。

タイトルとURLをコピーしました