Swift for iOS Development(8)-クラスと構造

バージョン

Xcode 11.3.1
Swift 5.1.3

Swiftの構造体とクラスの関数は非常に似ています。この記事で説明する関数のほとんどは構造体またはクラスで使用できるため、2つを同じ章に入れてください。

構造とクラスの比較

Swiftの構造とクラスには多くの共通点があります。どちらも次のようになります。

  • 値を格納する属性を定義する
  • 機能を提供するメソッドを定義する
  • 添え字構文を介してそれらの値にアクセスするための添え字操作を定義します
  • 初期値を設定するコンストラクターを定義します
  • デフォルトの実装を超えて機能を増やすために拡張する
  • プロトコルに従って、特定の標準機能を提供します

構造と比較すると、クラスには次の追加機能があります。

  • 継承により、あるクラスが別のクラスの特性を継承できます
  • 型変換により、実行時にクラスインスタンスの型を確認および解釈できます
  • デストラクタにより、クラスインスタンスは割り当てられたリソースを解放できます
  • 参照カウントにより、クラスへの複数の参照が可能になります

構造またはクラスを選択しますか?
このクラスでサポートされる追加機能には、複雑さが増すという犠牲が伴います。一般的なガイドラインに従って、次の1つ以上の条件が満たされたときに構造を構築することを検討してください。

  • この構造の主な目的は、関連する少量の単純なデータ値をカプセル化することです。
  • 構造体インスタンスが割り当てられるか渡されるときに、カプセル化されたデータが参照されるのではなくコピーされることを期待するのは合理的です。
  • 構造体に格納されている値型属性も、引用符で囲まれる代わりにコピーされます。
  • 構造体は、別の既存のタイプのプロパティまたは動作を継承する必要はありません。

たとえば、構造は次の状況での使用に適しています。

  • 幾何学的形状のサイズは、幅プロパティと高さプロパティをカプセル化します。どちらもダブルタイプです。
  • 特定の範囲内のパスは、開始属性と長さ属性をカプセル化します。これらは両方ともInt型です。
  • 3次元座標系の点は、x、y、zのプロパティをカプセル化します。これらはすべてDoubleタイプです。

タイプ定義とインスタンスの作成

// 定义结构体
struct Characteristic {
    
    
    var height = 0
    var weight = 0
}

// 定义类
class People {
    
    
    var name: String?
    var age = 0
    var characteristic = Characteristic()
}

// 实例化
// 类的实例化
let people = People()
// 结构体的实例化
var characteristic1 = Characteristic()
// 结构体的另一种方法实例化 (成员逐一构造器,类没有这种方法)
let characteristic2 = Characteristic(height: 180, weight: 200)

people.name = "小明"
people.age = 18
people.characteristic.height = 180
people.characteristic.weight = 150
print("\(people.name!)的年龄是\(people.age)岁,身高是\(people.characteristic.height)厘米,体重是\(people.characteristic.weight)斤")
// 小明的年龄是18岁,身高是180厘米,体重是150斤

characteristic1.height = 100;
characteristic1.weight = 50;
print("特征1 身高为\(characteristic1.height), 体重为\(characteristic1.weight)")
// 特征1 身高为100, 体重为50

print("特征2 身高为\(characteristic2.height), 体重为\(characteristic2.weight)")
// 特征2 身高为180, 体重为200

構造は値型です

値型は、変数、定数に割り当てられたとき、または関数に渡されたときに値がコピーされる型です。
たとえば、フィーチャ3を宣言し、フィーチャ2の値を前者に割り当ててから、フィーチャ3の高さと重量を変更し、フィーチャ2の値が変更に従わないことを確認します。

var characteristic3 = characteristic2
characteristic3.height = 200
characteristic3.weight = 300
print("特征2 身高为\(characteristic2.height), 体重为\(characteristic2.weight)")
print("特征3 身高为\(characteristic3.height), 体重为\(characteristic3.weight)")
// 特征2 身高为180, 体重为200
// 特征3 身高为200, 体重为300

実際、Swiftのすべての基本型(整数、浮動小数点数、ブール、文字列、配列、辞書)はすべて値型です。最下層も、構造体を使用して実装されます。

クラスは参照型です

値型とは異なり、参照型が変数、定数に割り当てられている場合、または関数に渡されている場合、その値はコピーされません。したがって、既存のインスタンスへの参照が使用され、そのコピーではありません。
たとえば、people1を宣言し、peopleを彼に割り当ててから、people1の名前を変更すると、元のpeopleも変更されていることがわかります。

let people1 = people
people1.name = "小红"
print("people 名称为\(people.name!)")
print("people1 名称为\(people1.name!)")
// people 名称为小红
// people1 名称为小红

people1は、変数ではなく定数として宣言されていることに注意してください。ただし、定数people1の値は変更されていないため、people1.nameなどのプロパティを変更することはできます。これらは、このPeopleインスタンスを「保存」するのではなく、Peopleインスタンスへの参照にすぎません。したがって、変更されたのは、Peopleへの定数参照の値ではなく、基になるPeopleインスタンスのname属性です。

恒等演算子

クラスは参照型であるため、複数の定数と変数がバックグラウンドで同時に同じクラスインスタンスを参照する場合があります。(構造体と列挙型の場合、これは当てはまりません。これらは値型であるため、定数、変数に割り当てられたとき、または関数に渡されたときに、それらの値は常にコピーされます。)
2つの定数または変数が参照されているかどうかを判断します同じクラスインスタンスが役立つ場合があります。この目標を達成するために、Swiftは2つのID演算子を提供します。

  • 同じ(===)
  • 同じではありません(!==)
if people1 === people {
    
    
    print("people1 和 people 引用同一个实例")
}
// 打印 people1 和 people 引用同一个实例

ポインター

C、C ++、またはObjective-C言語の経験がある場合は、これらの言語がポインターを使用してメモリ内のアドレスを参照していることをご存知かもしれません。Swiftは、参照型インスタンスの定数または変数を参照します。これは、C言語のポインターに似ていますが、メモリアドレスを直接指すわけではなく、アスタリスク(*)を使用してユーザーであることを示す必要もありません。参照を作成しています。対照的に、Swiftの参照は、他の定数または変数と同じ方法で定義されます。

おすすめ

転載: blog.csdn.net/u012078168/article/details/104350158