参照型の型変換
暗黙型変換
暗黙型変換は、コンパイラが自動的に行う型変換です。主にプリミティブ型と参照型の変換で使用されます。暗黙型変換は、型が互換性があり、データの損失がない場合に行われます。
プリミティブ型の暗黙型変換
Javaでは、あるプリミティブ型からより大きな範囲を持つプリミティブ型に変換する場合、暗黙的に変換が行われます。
public class Main {
public static void main(String[] args) {
int i = 10;
double d = i; // intからdoubleへの暗黙型変換
System.out.println(d); // 出力: 10.0
}
}
ここでは、int型からdouble型への暗黙的な変換が行われます。intの値がdoubleに変換されても、データが失われることはありません。
参照型の暗黙型変換
参照型では、サブクラスのインスタンスをスーパークラスの型として扱うことができます。これも暗黙的な型変換です。
class Animal {
void eat() {
System.out.println("Animal is eating");
}
}
class Dog extends Animal {
void bark() {
System.out.println("Dog is barking");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
Animal animal = dog; // DogからAnimalへの暗黙型変換
animal.eat(); // Animalクラスのメソッドを呼び出す
}
}
キャストによる型変換
キャストは、型を明示的に変換する方法です。Javaでは、型が互換性がない場合やデータの変換が必要な場合に使用します。キャストは、型変換の安全性を保障しません。特にダウンキャストでは、実行時にClassCastExceptionが発生する可能性があるため、注意が必要です。
プリミティブ型のキャスト
プリミティブ型のキャストでは、データの精度が変わることがあります。例えば、doubleからintへのキャストでは、小数部分が切り捨てられます。
public class Main {
public static void main(String[] args) {
double d = 10.5;
int i = (int) d; // doubleからintへのキャスト
System.out.println(i); // 出力: 10
}
}
参照型のキャスト
参照型のキャストでは、サブクラスのインスタンスをスーパークラスの型からサブクラスの型に変換することができます。ダウンキャストを行う際には、instanceof演算子を使って型を確認することが推奨されます。
class Animal {
void eat() {
System.out.println("Animal is eating");
}
}
class Dog extends Animal {
void bark() {
System.out.println("Dog is barking");
}
}
public class Main {
public static void main(String[] args) {
Animal animal = new Dog(); // アップキャスト
if (animal instanceof Dog) {
Dog dog = (Dog) animal; // ダウンキャスト
dog.bark(); // Dogクラスのメソッドを呼び出す
}
}
}
ポリモフィズム
ポリモフィズム(多様性)とは、オブジェクト指向プログラミングにおいて、同じ操作が異なるクラスのオブジェクトによって異なる方法で実行される能力を指します。Javaでは、ポリモフィズムは主に メソッドのオーバーライド と インターフェースの実装 によって実現されます。
ポリモフィズムの仕組み
ポリモフィズムを理解するためには、継承とメソッドのオーバーライドの概念が重要です。これらを用いることで、スーパークラスの型で定義されたメソッドが、サブクラスごとに異なる動作をするように実装できます。
1. 継承とメソッドのオーバーライド
継承を利用して、スーパークラスに定義されたメソッドをサブクラスでオーバーライド(上書き)できます。このオーバーライドにより、同じメソッド名でも、サブクラスごとに異なる実装を持たせることができます。
class Animal {
void makeSound() {
System.out.println("Some sound");
}
}
class Dog extends Animal {
@Override
void makeSound() {
System.out.println("Bark");
}
}
class Cat extends Animal {
@Override
void makeSound() {
System.out.println("Meow");
}
}
public class Main {
public static void main(String[] args) {
Animal myDog = new Dog();
Animal myCat = new Cat();
myDog.makeSound(); // 出力: Bark
myCat.makeSound(); // 出力: Meow
}
}
2. インターフェースの実装
ポリモフィズムはインタフェースを使っても実現できます。インタフェースは、クラスが実装しなければならないメソッドの宣言のみを含む型です。異なるクラスが同じインタフェースを実装することで、同じ操作を異なる方法で実行できます。
interface Animal {
void makeSound();
}
class Dog implements Animal {
@Override
public void makeSound() {
System.out.println("Bark");
}
}
class Cat implements Animal {
@Override
public void makeSound() {
System.out.println("Meow");
}
}
public class Main {
public static void main(String[] args) {
Animal myDog = new Dog();
Animal myCat = new Cat();
myDog.makeSound(); // 出力: Bark
myCat.makeSound(); // 出力: Meow
}
}
ポリモフィズムの利点
- 柔軟性の向上: 一つのインタフェースやスーパークラスの型を通じて、異なるクラスのオブジェクトを扱うことができるため、コードがより柔軟で拡張可能になります。
- コードの再利用: ポリモフィズムにより、同じコードを異なるオブジェクトに適用できるため、コードの再利用性が高まります。
- 保守性の向上: 新しいクラスを追加する際に既存のコードを変更する必要が少なくなり、保守性が向上します。
コレクション
コレクションは、データのグループを扱うためのフレームワークです。コレクションフレームワークは、データの格納、検索、操作、削除などを簡単かつ効率的に行えるように設計されています。コレクションには複数のインタフェース、クラス、およびメソッドが含まれており、それぞれが異なる種類のデータ構造やアルゴリズムを提供しています。
コレクションの基本インターフェース
1. Collection:
- コレクションの基本的な操作(要素の追加、削除、検索など)を定義するルートインターフェースです。
- 直接このインターフェースを実装するクラスは少なく、多くはこれを拡張した他のインタフェースを実装します。
2. List:
- 要素の順序が維持されるコレクションを表します。同じ要素を複数回格納することができます。
- 実装クラス:ArrayList、LinkedList、Vector
3. Set:
- 重複しない要素のコレクションを表します。要素の順序は保証されません。
- 実装クラス:HashSet、LinkedHashSet、TreeSet
4. Queue:
- 要素を先入れ先出し(FIFO)の順序で処理するコレクションを表します。
- 実装クラス:LinkedList、PriorityQuequ
5. Map:
- キーと値のペア(エントリー)を管理するコレクションです。キーは重複しませんが、値は重複しても構いません。
- 実装クラス:HashMap、TreeMap、LinkedHashMap
コレクションの実装クラス
コレクションフレームワークには、様々な実装クラスがあり、それぞれ異なる特徴を持っています。いかにいくつかの代表的なクラスを紹介します。
1. ArrayList
- 特徴: 可変長配列として機能し、ランダムアクセスが高速です。
- 用途: 順序が重要で、頻繁に読み取りが行われる場合に使用します。
List<String> arrayList = new ArrayList<>();
arrayList.add("Apple");
arrayList.add("Banana");
System.out.println(arrayList.get(1)); // 出力: Banana
2. LinkedList
- 特徴: 双方向リストを実装しており、挿入や削除が高速です。
- 用途: 頻繁に要素の追加や削除が行われる場合に使用します。
List<String> linkedList = new LinkedList<>();
linkedList.add("Apple");
linkedList.add("Banana");
linkedList.remove(0);
System.out.println(linkedList.get(0)); // 出力: Banana
3. HashSet
- 特徴: 要素の順序が保証されず、重要要素を許容しません。ハッシュテーブルを使用しているため、高速な検索、追加、削除が可能です。
- 用途: 重複しない要素のコレクションが必要な場合に使用します。
Set<String> hashSet = new HashSet<>();
hashSet.add("Apple");
hashSet.add("Banana");
hashSet.add("Apple"); // 重複要素は追加されない
System.out.println(hashSet.size()); // 出力: 2
4. HashMap
- 特徴: キーと値のペアを格納し、キーの重複を許可しません。ハッシュテーブルを使用しており、高速な検索が可能です。
- 用途: キーとそれに対応する値を管理する必要がある場合に使用します。
Map<String, Integer> hashMap = new HashMap<>();
hashMap.put("Apple", 1);
hashMap.put("Banana", 2);
System.out.println(hashMap.get("Apple")); // 出力: 1
コレクションの操作
コレクションフレームワークには、要素を操作するための多くの便利なメソッドがあります。
- 要素の追加: add(E e)、put(K k, V v)(Mapの場合)
- 要素の削除: remove(Object o)、remove(K key)(Mapの場合)
- 要素の取得: get(int index)、get(Object key)(Mapの場合)
- サイズの取得: size()
- 要素の存在確認: contains(Object o)、containsKey(Object key)(Mapの場合)
最初のページ
[備忘録 その1] Java Silver ~Javaプログラミング基礎~