* 내가 읽으려고 내 맘대로 번역한 글.
* 원문 : https://docs.swift.org/swift-book/LanguageGuide/Inheritance.html

 

 

 

 

 

Inheritance

A class can inherit methods, properties, and other characteristics from another class. When one class inherits from another, the inheriting class is known as a subclass, and the class it inherits from is known as its superclass. Inheritance is a fundamental behavior that differentiates classes from other types in Swift.

클래스는 메소드, 속성, 다른 특성들을 다른 클래스로 부터 상속받을수 있다.

어떤 클래스가 다른 클래스로부터 상속 받았을때, 상속받은 클래스를 서브클래스라고 하고,

상속해준 클래스를 슈퍼클래스라고 한다.

상속은 swift에서 다른 타입들과 구분되는 클래스의 기본적인 동작이다.

 

Classes in Swift can call and access methods, properties, and subscripts belonging to their superclass and can provide their own overriding versions of those methods, properties, and subscripts to refine or modify their behavior. Swift helps to ensure your overrides are correct by checking that the override definition has a matching superclass definition.

swift에서 클래스는 슈퍼클래스에 속해있는 메소드, 속성, 첨자를 호출하고 접근할수 있다.

그리고 그 동작들을 수정하고 다시 정의해서 자신만의 메소드, 속성, 첨자의 오버라이드 버젼을 제공할수 있다.

swift는 슈퍼클래스가 너의 오버라이드 정의와 일치하는 정의를 가지고 있는지 검사해서

너의 오버라이드가 올바른지 확인하는데 도움을 준다.

 

Classes can also add property observers to inherited properties in order to be notified when the value of a property changes. Property observers can be added to any property, regardless of whether it was originally defined as a stored or computed property.

클래스는 상속된 속성에 속성 옵저버를 추가할수 있어서 속성의 값이 변했을때 알려줄수 있다.

속성 옵저버는 원래 속성이 저장 속성인지 계산된 속성인지 관계없이 어떤 속성에도 추가할수 있다.

 

Defining a Base Class

Any class that does not inherit from another class is known as a base class.

다른 클래스로 부터 상속받지 않은 클래스는 모두 베이스 클래스다.

 

NOTE

Swift classes do not inherit from a universal base class. Classes you define without specifying a superclass automatically become base classes for you to build upon.

swift 클래스는 범용 베이스 클래스를 상속받지 않는다.

슈퍼클래스를 지정하지 않은 클래스는 자동으로 베이스 클래스가 된다.

 

The example below defines a base class called Vehicle. This base class defines a stored property called currentSpeed, with a default value of 0.0 (inferring a property type of Double). The currentSpeed property’s value is used by a read-only computed String property called description to create a description of the vehicle.

아래 예제는 Vehicle 이라는 베이스 클래스를 정의한다.

이 베이스클래스는 currentSpeed라는 저장속성을 정의하고 초기값으로 0.0 (속성타입은 Double로 추정).

currentSpeed 속성의 값은 description이라는 읽기전용 계산 문자열 속성에 의해서 사용되어서 운송수단의 설명을 만든다.

 

The Vehicle base class also defines a method called makeNoise. This method does not actually do anything for a base Vehicle instance, but will be customized by subclasses of Vehicle later on:

Vehicle 베이스 클래스는 makeNoise 라는 메소드도 정의하였다.

이  메소드는 사실 Vehicle 인스턴스에서는 아무것도 안하지만, 나중에 서브클래스에서 목정게 맞게 바꾸게 될것이다.

class Vehicle {
	var currentSpeed = 0.0
	var description: String {
		return "traveling at \(currentSpeed) miles per hour"
	}
	func makeNoise() {
		// do nothing - an arbitrary vehicle doesn't necessarily make a noise
	}
}

 

You create a new instance of Vehicle with initializer syntax, which is written as a type name followed by empty parentheses:

초기화 문법으로 Vehicle의 새로운 인스턴스를 만들수 있다. 여기서는 타입 이름 뒤에 빈 괄호를 썼다.

let someVehicle = Vehicle()

 

Having created a new Vehicle instance, you can access its description property to print a human-readable description of the vehicle’s current speed:

새로운 Vehicle 인스턴스를 가지고, 운송수단의 현재 속도를 사람이 읽을수 있게 출력하기 위하여 description 속성에 접근가능하다.

print("Vehicle: \(someVehicle.description)")
// Vehicle: traveling at 0.0 miles per hour

 

The Vehicle class defines common characteristics for an arbitrary vehicle, but is not much use in itself. To make it more useful, you need to refine it to describe more specific kinds of vehicles.

Vehicle 클래스는 임의의 운송수단에 대한 공통된 특징을 정의하지만, 이것 자체로는 많이 유용하지 않다.

이걸 더 유용하게 만들려면 더 구체적인 운송수단을 설명할수 있도록 재정의가 필요하다.

 

Subclassing

Subclassing is the act of basing a new class on an existing class. The subclass inherits characteristics from the existing class, which you can then refine. You can also add new characteristics to the subclass.

subclassing은 기존 클래스를 바탕으로 새로운 클래스를 만드는 행위이다.

서브클래스는 기존의 클래스로 부터 특징을 상속하고, 재정의할수 있다.

또한 서브클래스에 새로운 특징을 추가할수도 있다.

 

To indicate that a subclass has a superclass, write the subclass name before the superclass name, separated by a colon:

서브클래스가 슈퍼클래스를 가지고 있다는걸 표시하려면, 서브클래스 이름 쓰고 콜론쓰고 슈퍼클래스 이름 써라.

class SomeSubclass: SomeSuperclass {
	// subclass definition goes here
}

 

The following example defines a subclass called Bicycle, with a superclass of Vehicle:

아래 예제는 Bicycle 이라는 서브클래스를 정의하였고, 슈퍼클래스는 Vehicle 이다.

class Bicycle: Vehicle {
	var hasBasket = false
}

 

The new Bicycle class automatically gains all of the characteristics of Vehicle, such as its currentSpeed and description properties and its makeNoise() method.

새로운 Bicyle 클래스는 자동으로 Vehicle의 모든 특성을 가진다.

currentSpeed, description 속성과 makeNoise 메소드 같은것들.

 

In addition to the characteristics it inherits, the Bicycle class defines a new stored property, hasBasket, with a default value of false (inferring a type of Bool for the property).

상속된 특성에 더하여, Bicycle 클래스는 새로운 저장속성 hasBasket을 정의하였고, 기본값은 false 다.

(속성은 Bool 타입으로 추정됨)

 

By default, any new Bicycle instance you create will not have a basket. You can set the hasBasket property to true for a particular Bicycle instance after that instance is created:

기본적으로, 모든 새로운 Bicycle 인스턴스는 바구니를 가지고 있지 않다.

인스턴스가 생성된후 특정 Bicycle 인스턴스의 hasBasket 속성을 true로 설정할수 있다.

let bicycle = Bicycle()
bicycle.hasBasket = true

 

You can also modify the inherited currentSpeed property of a Bicycle instance, and query the instance’s inherited description property:

또한 Bicycle 인스턴스에서 상속된 currentSpeed 속성을 수정할수 있고, 인스턴스의 상속된 description 속성을 조회할수 있다.

bicycle.currentSpeed = 15.0
print("Bicycle: \(bicycle.description)")
// Bicycle: traveling at 15.0 miles per hour

 

Subclasses can themselves be subclassed. The next example creates a subclass of Bicycle for a two-seater bicycle known as a “tandem”:

서브클래스를 상속받아 또 서브클래스를 만들수 있다.

다음 예제는 tandem이라고 알려진 의자가 2개있는 자전거를 위하여 Bicycle 의 서브클래스를 만든다.

class Tandem: Bicycle {
	var currentNumberOfPassengers = 0
}

 

Tandem inherits all of the properties and methods from Bicycle, which in turn inherits all of the properties and methods from Vehicle. The Tandem subclass also adds a new stored property called currentNumberOfPassengers, with a default value of 0.

Tandem은 Bicycle로 부터 모든 속성과 메소드를 상속받았고, Bicycle은 Vehicle로 부터 모든 속성과 메소드를 상속받았다.

Tandem 서브클래스는 역시 새로운 속성 currentNumberOfPassengers를 추가하였고, 기본값은 0 이다.

 

If you create an instance of Tandem, you can work with any of its new and inherited properties, and query the read-only description property it inherits from Vehicle:

Tandem의 인스턴스를 만들면, 새로 추가었거나 상속받은 속성들을 사용가능하고,

Vehicle로 부터 상속받은 읽기전용 description 속성도 조회 할수 있다.

let tandem = Tandem()
tandem.hasBasket = true
tandem.currentNumberOfPassengers = 2
tandem.currentSpeed = 22.0
print("Tandem: \(tandem.description)")
// Tandem: traveling at 22.0 miles per hour

 

Overriding

A subclass can provide its own custom implementation of an instance method, type method, instance property, type property, or subscript that it would otherwise inherit from a superclass. This is known as overriding.

서브클래스는 슈퍼클래스에서 상속받은 인스턴스 메소드, 타입 메소드, 인스턴스 속성, 타입 속성, 첨자들을 커스텀 구현할수 있다.

이것을 오버라이딩 이라고 한다.

 

To override a characteristic that would otherwise be inherited, you prefix your overriding definition with the override keyword. Doing so clarifies that you intend to provide an override and have not provided a matching definition by mistake. Overriding by accident can cause unexpected behavior, and any overrides without the override keyword are diagnosed as an error when your code is compiled.

상속된 특성을 오버라이드하려면, 오버라이딩 정의에 접두사 override 키워드를 붙여라.

이렇게 해서 일치하는 정의가 없는것을 실수로 오버라이드 하려는 너의 의도가 명확히 들어나게 해라.

실수로 오버라이딩하는것은 예상할수 없는 행동을 야기시키고,

override 키워드 없이 오버라이딩하면 너의 코드가 컴파일될때 에러로 진단된다.

 

The override keyword also prompts the Swift compiler to check that your overriding class’s superclass (or one of its parents) has a declaration that matches the one you provided for the override. This check ensures that your overriding definition is correct.

override 키워드는 swift 컴파일러가 슈퍼클래스에서 일치하는 정의가 있는지 검사하도록 한다.

이 검사는 너의 오버라이딩 정의가 올바른지를 확인해준다.

 

Accessing Superclass Methods, Properties, and Subscripts

When you provide a method, property, or subscript override for a subclass, it is sometimes useful to use the existing superclass implementation as part of your override. For example, you can refine the behavior of that existing implementation, or store a modified value in an existing inherited variable.

서브클래스에서 메소드, 속성, 첨자를 오버라이드 할때, 기존의 슈퍼클래스 구현을 오버라이드의 일부로 사용하는것은 유용할때가 있다.

예를들어, 기존 구현의 행동을 더 발전시키거나, 기존에 상속받은 변수의 값을 수정해서 저장할수 있다.

 

Where this is appropriate, you access the superclass version of a method, property, or subscript by using the super prefix:

super 접두사를 이용해서 슈퍼클래스 버젼의 메소드, 속성, 첨자에 접근하는 적절한 경우다.

  • An overridden method named someMethod() can call the superclass version of someMethod() by calling super.someMethod() within the overriding method implementation.
  • An overridden property called someProperty can access the superclass version of someProperty as super.someProperty within the overriding getter or setter implementation.
  • An overridden subscript for someIndex can access the superclass version of the same subscript as super[someIndex] from within the overriding subscript implementation.
  • 오버라이드된 someMethod()는 자신의 구현안에서 super.someMethod() 로 슈퍼클래스의 메소드를 호출할수 있다.
  • 오버라이드된 someProperty 속성은 자신의 getter와 setter에서 super.someProperty 로 슈퍼클래스의 속성에 접근할수 있다.
  • 오버라이드된 someIndex 첨자는 자신의 구현안에서 super[someIndex] 로 슈퍼클래스의 속성에 접근할수 있다.

 

Overriding Methods

You can override an inherited instance or type method to provide a tailored or alternative implementation of the method within your subclass.

상속된 인스턴스 메소드, 타입 메소드를 너의 서브클래스에서 오버라이드해서 맞춤형 또는 대체 구현을 제공할수 있다.

 

The following example defines a new subclass of Vehicle called Train, which overrides the makeNoise() method that Train inherits from Vehicle:

다음 예제는 Train 이라는 Vehicle의 새로운 서브클래스를 정의하고, 상속받은 makeNoise() 메소드를 오버라이드 한다.

class Train: Vehicle {
	override func makeNoise() {
		print("Choo Choo")
	}
}

 

If you create a new instance of Train and call its makeNoise() method, you can see that the Train subclass version of the method is called:

Train의 새로운 인스턴스를 만들고, makeNoise() 메소드를 호출하면, Train 서비클래스 버젼의 메소드가 호출되는걸 보게 된다.

let train = Train()
train.makeNoise()
// Prints "Choo Choo"

 

Overriding Properties

You can override an inherited instance or type property to provide your own custom getter and setter for that property, or to add property observers to enable the overriding property to observe when the underlying property value changes.

상속된 인스턴스 속성, 타입 속성을 오버라이드 해서 커스텀 getter와 setter를 제공할수 있고,

속성 옵저버를 추가하여 속성값이 변했을때 오버라이딩 된 속성을 관찬할수 있다.

 

 

Overriding Property Getters and Setters

You can provide a custom getter (and setter, if appropriate) to override any inherited property, regardless of whether the inherited property is implemented as a stored or computed property at source. The stored or computed nature of an inherited property is not known by a subclass—it only knows that the inherited property has a certain name and type. You must always state both the name and the type of the property you are overriding, to enable the compiler to check that your override matches a superclass property with the same name and type.

상속된 속성을 오버라이드 해서 커스컴 getter, setter를 제공할수 있고, 상속된 속성이 저장속성인지 계산된속성인지 상관없다.

상속된 속성이 저장속성인지 계산된속성인지 서브클래스에서는 알수 없다. 상속된 속성의 이름과 타입만 알수 있다.

항상 오버라이딩 하려는 속성의 이름과 타입을 분명히 해서, 컴파일러가 슈퍼클래스에서 이름과 타입이 일치하는 속성을

검사하도록 해야 한다.

 

You can present an inherited read-only property as a read-write property by providing both a getter and a setter in your subclass property override. You cannot, however, present an inherited read-write property as a read-only property.

상속된 읽기전용 속성을 서브클래스의 오버라이드에서 getter와 setter을 제공해 읽기쓰기 속성으로 만들수 있다.

하지만 상속된 읽기쓰기 속성을 읽기전용 속성으로 오버라이딩 할수는 없다.

 

NOTE

If you provide a setter as part of a property override, you must also provide a getter for that override. If you don’t want to modify the inherited property’s value within the overriding getter, you can simply pass through the inherited value by returning super.someProperty from the getter, where someProperty is the name of the property you are overriding.

속성을 오버라이드해서 setter를 만들면, getter도 만들어야 한다.

오버라이딩 getter에서 상속된 속성의 값을 바꾸기 원하지 않으면, 단순히 super.someProperty를 리턴해서 상속된 값을 전달할수 있다.

여기서 someProperty 는 너가 오버라이딩 하려는 속성의 이름이다.

 

The following example defines a new class called Car, which is a subclass of Vehicle. The Car class introduces a new stored property called gear, with a default integer value of 1. The Car class also overrides the description property it inherits from Vehicle, to provide a custom description that includes the current gear:

다음 예제는 Car라는 새로운 클래스를 정의한다. Vehicle의 서브클래스다.

Car 클래스는 새로운 저장 속성 gear를 만들었고, 기본값은 숫자 1 이다.

Car 클래스는 Vehicle에서 상속받은 description 속성을 오버라이드 해서, 현재 기어의 커스텀 설명을 제공한다.

class Car: Vehicle {
	var gear = 1
	override var description: String {
		return super.description + " in gear \(gear)"
	}
}

 

The override of the description property starts by calling super.description, which returns the Vehicle class’s description property. The Car class’s version of description then adds some extra text onto the end of this description to provide information about the current gear.

description 속성의 오버라이드는 Vehicle 클래스의 description 속성을 리턴하는 super.description을 호출하는걸로 시작한다.

description의 Car 클래스 버젼은 현재 기어에 대한 정보를 제공하기 위하여 description 뒤에 추가적인 텍스트를 넣었다.

 

If you create an instance of the Car class and set its gear and currentSpeed properties, you can see that its description property returns the tailored description defined within the Car class:

Car 클래스의 인스턴스를 만들고, gear 와 currentSpeed 속성을 설정하면,

Car 클래스 안에서 정의된 맞춤형 description 속성이 리턴되는걸 볼수 있다.

let car = Car()
car.currentSpeed = 25.0
car.gear = 3
print("Car: \(car.description)")
// Car: traveling at 25.0 miles per hour in gear 3

 

Overriding Property Observers

You can use property overriding to add property observers to an inherited property. This enables you to be notified when the value of an inherited property changes, regardless of how that property was originally implemented. For more information on property observers, see Property Observers.

상속된 속성에 속성 옵저버를 추가하기 위해 속성 오버라이딩을 사용할수 있다.

이것은 원래 어떻게 구현되었든지 상관없이 상속된 속성 값이 변하는것을 알려준다.

 

NOTE

You cannot add property observers to inherited constant stored properties or inherited read-only computed properties. The value of these properties cannot be set, and so it is not appropriate to provide a willSet or didSet implementation as part of an override.

Note also that you cannot provide both an overriding setter and an overriding property observer for the same property. If you want to observe changes to a property’s value, and you are already providing a custom setter for that property, you can simply observe any value changes from within the custom setter.

상속된 상수 속성과 상속된 읽기전용 계산된 속성에는 속성 옵저버를 추가할수 없다.

이 속성들의 값은 설정될수 없어서, 오버라이드에서 willSet 과 didSet을 제공하는것을 적절하지 않다.

이 속성들에는 오버라이딩 setter와 오버라이딩 속성 옵저버를 추가할수 없다는걸 주목해라.

이미 커스텀 setter를 제공하는 속성에, 속성의 값이 변하는걸 관찰하고 싶으면, 간단히 커스텀 setter에서 값이 변하는걸 관찰할수 있다.

 

The following example defines a new class called AutomaticCar, which is a subclass of Car. The AutomaticCar class represents a car with an automatic gearbox, which automatically selects an appropriate gear to use based on the current speed:

다음 예제는 Car의 서브클래스인 AutomaticCar라른 새로운 클래스를 정의한다.

AutomaticCar 클래스는 자동기어박스를 가진 차를 표현해서, 현재 속도에 따른 적절한 기어를 자동으로 선택한다.

class AutomaticCar: Car {
	override var currentSpeed: Double {
		didSet {
			gear = Int(currentSpeed / 10.0) + 1
		}
	}
}

 

Whenever you set the currentSpeed property of an AutomaticCar instance, the property’s didSet observer sets the instance’s gear property to an appropriate choice of gear for the new speed. Specifically, the property observer chooses a gear that is the new currentSpeed value divided by 10, rounded down to the nearest integer, plus 1. A speed of 35.0 produces a gear of 4:

AutomaticCar 인스턴스의 currentSpeed 속성을 설정할때마다,

didSet 옵저버가 인스턴스의 gear 속성에 새로운 속도에 대한 적절한 기어를 선택해서 설정한다.

특히 속성 옵저버는 새로운 currentSpeed 값을 10으로 나누고, 가장 가까운 정수로 내림하고, 1을 더해서 기어를 선택한다.

35.0 속도는 기어를 4로 만든다.

let automatic = AutomaticCar()
automatic.currentSpeed = 35.0
print("AutomaticCar: \(automatic.description)")
// AutomaticCar: traveling at 35.0 miles per hour in gear 4

 

Preventing Overrides

You can prevent a method, property, or subscript from being overridden by marking it as final. Do this by writing the final modifier before the method, property, or subscript’s introducer keyword (such as final var, final func, final class func, and final subscript).

메소드, 속성, 첨자에 final 을 써서 오버라이드 되는걸 막을수 있다.

메소드, 속성, 첨자의 키워드 앞에 final 을 붙여라.

(final var, final func, final class func, final subscript 처럼)

 

Any attempt to override a final method, property, or subscript in a subclass is reported as a compile-time error. Methods, properties, or subscripts that you add to a class in an extension can also be marked as final within the extension’s definition.

final 메소드, 속성, 첨자를 서브클래스에서 오버라이드 하려는 시도는 컴파일 에러를 낸다.

서브클래스에서 추가한 메소드, 속성, 첨자에도 역시 final 을 붙일수 있다.

 

You can mark an entire class as final by writing the final modifier before the class keyword in its class definition (final class). Any attempt to subclass a final class is reported as a compile-time error.

클래스 선언 키워드 앞에 final을 붙여서 클래스 전체를 final 로 만들수 있다 (final class)

final 클래스에서 상속받으려는 시도는 컴파일 에러를 낸다.

반응형

'iOS 초보' 카테고리의 다른 글

[swift5.1번역] 15.Deinitialization  (0) 2019.09.17
[swift5.1번역] 14.Initialization  (0) 2019.09.04
[swift5.1번역] 12.Subscripts  (0) 2019.08.21
[swift5.1번역] 11.Methods  (0) 2019.08.19
[swift5.1번역] 10.Properties  (0) 2019.08.14
Posted by 돌비
,