F # - Наследование
Одна из наиболее важных концепций объектно-ориентированного программирования - это наследование. Наследование позволяет нам определять класс в терминах другого класса, что упрощает создание и поддержку приложения. Это также дает возможность повторно использовать функциональность кода и быстрое время реализации.
При создании класса вместо написания полностью новых элементов данных и функций-членов программист может указать, что новый класс должен наследовать члены существующего класса. Этот существующий класс называется базовым классом, а новый класс - производным классом.
Идея наследования реализует отношения 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
Теперь метод Greet класса Person можно переопределить в производных классах. Следующий пример демонстрирует это -
пример
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.