F #-상속
객체 지향 프로그래밍에서 가장 중요한 개념 중 하나는 상속입니다. 상속을 통해 다른 클래스의 관점에서 클래스를 정의 할 수 있으므로 응용 프로그램을 쉽게 만들고 유지 관리 할 수 있습니다. 또한 코드 기능을 재사용 할 수있는 기회와 빠른 구현 시간을 제공합니다.
클래스를 만들 때 완전히 새로운 데이터 멤버와 멤버 함수를 작성하는 대신 프로그래머는 새 클래스가 기존 클래스의 멤버를 상속하도록 지정할 수 있습니다. 이 기존 클래스를 기본 클래스라고하고 새 클래스를 파생 클래스라고합니다.
상속 개념은 IS-A 관계를 구현합니다. 예를 들어, 포유류 IS A 동물, 개 IS-A 포유류 따라서 개 IS-A 동물도 마찬가지입니다.
기본 클래스 및 하위 클래스
하위 클래스는 이미 정의 된 기본 클래스에서 파생됩니다. 하위 클래스는 기본 클래스의 멤버를 상속 할뿐만 아니라 자체 멤버도 있습니다.
서브 클래스는 inherit 아래와 같이 키워드-
type MyDerived(...) =
inherit MyBase(...)
F #에서 클래스는 최대 하나의 직접 기본 클래스를 가질 수 있습니다. 다음을 사용하여 기본 클래스를 지정하지 않은 경우inherit 키워드에서 클래스는 Object에서 암시 적으로 상속합니다.
참고-
기본 클래스의 메서드와 멤버는 파생 클래스의 직접 멤버처럼 파생 클래스의 사용자가 사용할 수 있습니다.
바인딩 및 생성자 매개 변수는 클래스 전용이므로 파생 클래스에서 액세스 할 수 없습니다.
키워드 base기본 클래스 인스턴스를 나타냅니다. 자기 식별자처럼 사용됩니다.
예
type Person(name) =
member x.Name = name
member x.Greet() = printfn "Hi, I'm %s" x.Name
type Student(name, studentID : int) =
inherit Person(name)
let mutable _GPA = 0.0
member x.StudentID = studentID
member x.GPA
with get() = _GPA
and set value = _GPA <- value
type Teacher(name, expertise : string) =
inherit Person(name)
let mutable _salary = 0.0
member x.Salary
with get() = _salary
and set value = _salary <- value
member x.Expertise = expertise
//using the subclasses
let p = new Person("Mohan")
let st = new Student("Zara", 1234)
let tr = new Teacher("Mariam", "Java")
p.Greet()
st.Greet()
tr.Greet()
프로그램을 컴파일하고 실행하면 다음과 같은 출력이 생성됩니다.
Hi, I'm Mohan
Hi, I'm Zara
Hi, I'm Mariam
메서드 재정의
기본 클래스 메서드의 기본 동작을 재정의하고 하위 클래스 또는 파생 클래스에서 다르게 구현할 수 있습니다.
F #의 메서드는 기본적으로 재정의 할 수 없습니다.
파생 클래스의 메서드를 재정의하려면 다음을 사용하여 메서드를 재정의 가능으로 선언해야합니다. abstract 과 default 다음과 같이 키워드-
type Person(name) =
member x.Name = name
abstract Greet : unit -> unit
default x.Greet() = printfn "Hi, I'm %s" x.Name
이제 Person 클래스 의 Greet 메서드를 파생 클래스에서 재정의 할 수 있습니다. 다음 예제는 이것을 보여줍니다-
예
type Person(name) =
member x.Name = name
abstract Greet : unit -> unit
default x.Greet() = printfn "Hi, I'm %s" x.Name
type Student(name, studentID : int) =
inherit Person(name)
let mutable _GPA = 0.0
member x.StudentID = studentID
member x.GPA
with get() = _GPA
and set value = _GPA <- value
override x.Greet() = printfn "Student %s" x.Name
type Teacher(name, expertise : string) =
inherit Person(name)
let mutable _salary = 0.0
member x.Salary
with get() = _salary
and set value = _salary <- value
member x.Expertise = expertise
override x.Greet() = printfn "Teacher %s." x.Name
//using the subclasses
let p = new Person("Mohan")
let st = new Student("Zara", 1234)
let tr = new Teacher("Mariam", "Java")
//default Greet
p.Greet()
//Overriden Greet
st.Greet()
tr.Greet()
프로그램을 컴파일하고 실행하면 다음과 같은 출력이 생성됩니다.
Hi, I'm Mohan
Student Zara
Teacher Mariam.
추상 클래스
때로는 현실적으로 구현해서는 안되는 불완전한 객체 구현을 제공해야합니다. 나중에 다른 프로그래머는 완전한 구현을 위해 추상 클래스의 하위 클래스를 만들어야합니다.
예를 들어, Person 클래스는 학교 관리 시스템에서 필요하지 않습니다. 그러나 학생 또는 교사 클래스가 필요합니다. 이러한 경우 Person 클래스를 추상 클래스로 선언 할 수 있습니다.
그만큼 AbstractClass 속성은 컴파일러에게 클래스에 추상 멤버가 있음을 알려줍니다.
클래스가 완전히 구현되지 않았기 때문에 추상 클래스의 인스턴스를 만들 수 없습니다.
다음 예제는 이것을 보여줍니다-
예
[<AbstractClass>]
type Person(name) =
member x.Name = name
abstract Greet : unit -> unit
type Student(name, studentID : int) =
inherit Person(name)
let mutable _GPA = 0.0
member x.StudentID = studentID
member x.GPA
with get() = _GPA
and set value = _GPA <- value
override x.Greet() = printfn "Student %s" x.Name
type Teacher(name, expertise : string) =
inherit Person(name)
let mutable _salary = 0.0
member x.Salary
with get() = _salary
and set value = _salary <- value
member x.Expertise = expertise
override x.Greet() = printfn "Teacher %s." x.Name
let st = new Student("Zara", 1234)
let tr = new Teacher("Mariam", "Java")
//Overriden Greet
st.Greet()
tr.Greet()
프로그램을 컴파일하고 실행하면 다음과 같은 출력이 생성됩니다.
Student Zara
Teacher Mariam.