Skip to content

Instantly share code, notes, and snippets.

@chuck0523
Created April 18, 2016 12:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chuck0523/243819b3890246b8824394658f0acbeb to your computer and use it in GitHub Desktop.
Save chuck0523/243819b3890246b8824394658f0acbeb to your computer and use it in GitHub Desktop.
/*
オブジェクトとクラス
*/
// クラスはクラス名を指定することで作成できる。
// クラス内のプロパティの宣言は定数や変数の宣言と同様。メソッドや関数の宣言も同様。
class Shape {
var numberOfSides = 0
func simpleDescription() -> String {
return "A shape with \(numberOfSides)."
}
}
// ex: letでプロパティを追加して、引数のあるメソッドを追加してみる。
class ShapeTwo {
let numberOfSides = 0
func simpleDescription(name: String) -> String {
return "Hi \(name)! A shape with \(numberOfSides)."
}
}
// クラス名のあとに()を追加することでインスタンスを生成できる。プロパティやメソッドへのアクセスはドットを使う。
var shape = Shape()
shape.numberOfSides = 7
var shapeDescription = shape.simpleDescription()
// initを使うことでインスタンス生成時の初期化ができる。
class NamedShape {
var numberOfSides: Int = 0
var name: String
init(name: String) {
self.name = name
}
func simpleDescription() -> String {
return "A shape with \(numberOfSides) sides."
}
}
// init内でself.nameとすることで引数のnameと区別できる。
// 全てのプロパティには、値が割り当てられる必要がある。init内での割り当ても可。
// deinitを使うと、インスタンスの消去時の処理を指定することができる。
// サブクラスはスーパークラスの名前を後続させることができる。名前はコロンで区切る。
// 親クラスのメソッドを上書きする場合は、overrideを記述する。
// overrideを書かずに親クラスのメソッドを上書きしてしまうと、コンパイラがerrorを吐く。
// 一方で、上書きでないにも関わらずoverrideと書くとそれもコンパイラが感知する。
class Square: NamedShape {
var sideLength: Double
init(sideLength: Double, name: String) {
self.sideLength = sideLength
super.init(name: name)
numberOfSides = 4
}
func area() -> Double {
return sideLength * sideLength
}
override func simpleDescription() -> String {
return "A square with sides of length \(sideLength)."
}
}
let test = Square(sideLength: 5.2, name: "my test square")
test.area()
test.simpleDescription()
// ex: 別のクラスを作ってみる。
class Circle: NamedShape {
var radius: Double
init(radius: Double, name: String) {
self.radius = radius
super.init(name: name)
}
func area() -> Double {
return radius * radius * 3.14
}
override func simpleDescription() -> String {
return "A circle."
}
}
// プロパティはゲッターとセッターを持つことができる。
class EquilateralTriangle: NamedShape {
var sideLength: Double = 0.0
init(sideLength: Double, name: String) {
self.sideLength = sideLength
super.init(name: name)
numberOfSides = 3
}
var perimeter: Double {
get {
return 3.0 * sideLength
}
set {
sideLength = newValue / 3.0
}
}
override func simpleDescription() -> String {
return "An equialateral triangle with sides of length \(sideLength)."
}
}
var triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle")
print(triangle.perimeter)
triangle.perimeter = 9.9
print(triangle.sideLength)
// セッターのperimeterでは、新しく受け取る値はnewValueという暗黙的な名前をもつ。setの後に()をつけて明示することも可能。
// EquilateralTriangleのinitは3つの異なるステップを持つ。
// 1. サブクラスで定義したプロパティに値をセットする。
// 2. スーパークラスのinitを呼ぶ。
// 3. スーパークラスで定義されたプロパティの値を変更する。
// newValueをセットする前後で何かしらの処理が必要なときは、willSetかdidSetを使う。
class TriangleAndSquare {
var triangle: EquilateralTriangle {
willSet {
square.sideLength = newValue.sideLength
}
}
var square: Square {
willSet {
triangle.sideLength = newValue.sideLength
}
}
init(size: Double, name: String) {
square = Square(sideLength: size, name: name)
triangle = EquilateralTriangle(sideLength: size, name: name)
}
}
var triangleAndSquare = TriangleAndSquare(size: 10, name: "another test shape")
print(triangleAndSquare.square.sideLength)
print(triangleAndSquare.triangle.sideLength)
triangleAndSquare.square = Square(sideLength: 50, name: "larger square")
print(triangleAndSquare.triangle.sideLength)
// オプショナルな値を用いることも可能。
// ?の前の値がnilならば、?の後の式は全て無視されて、式全体の値はnilとなる。
let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square")
let sideLength = optionalSquare?.sideLength
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment