糖醋排骨是什么菜系| 6月1是什么星座| lo娘是什么意思| 女人排卵期有什么反应| 京东公司全称是什么| 神经外科和神经内科有什么区别| 三线炎有什么症状| 为什么要长智齿| 丰都为什么叫鬼城| 西地那非是什么| 血糖仪h1是什么意思| 为什么头皮会疼| 面瘫吃什么药好得快| 感冒适合吃什么饭菜| 心脏房颤是什么原因| 肾素高说明什么| 个体户是什么职业| 舌苔厚白中间有裂纹吃什么药| ad滴剂什么时候吃最好| 猪咳嗽用什么药好得快| 脚气病缺什么维生素| 丝瓜水敷脸有什么作用| gg是什么牌子的包包| 小孩子手足口病有什么症状图片| 户籍地填什么| 海瓜子是什么| 草字头加全念什么| 脐橙是什么意思| 孕期长痘痘是什么原因| 血精是什么原因| 什么米之乡| 尿道炎症吃什么药| 美女什么都没有穿| 右侧胸口疼是什么原因| 伏天吃羊肉有什么好处| 为什么有眼袋是什么原因引起的| 无印良品属于什么档次| 什么叫流年| 减肥期间晚上吃什么| 过敏性鼻炎吃什么药好| 打更是什么意思| 独美是什么意思| 大姨妈期间不能吃什么东西| 蝶窦囊肿是什么病| 肠粉是什么做的| 甲钴胺片是治什么病| 胎儿左心室灶状强回声是什么意思| 下面有异味是什么原因| 舌根白苔厚是什么原因| 对联又称什么| 鸡拉绿色粪便吃什么药| 负罪感是什么意思| fna是什么意思| 每天熬夜有什么危害| 孽缘什么意思| 鱼有念什么| 吃什么水果可以变白| 市公安局长什么级别| lg是什么牌子| 土命适合什么颜色| 诸葛亮老婆叫什么名字| 请问今晚买什么生肖| mlb是什么品牌| 碳13是检查什么的| 红光对皮肤有什么作用| 发烧有什么好处| 一什么招牌| 结售汇是什么意思| 媾什么意思| 膝盖痛什么原因| 小寄居蟹吃什么| 鲥鱼是什么鱼| 土固念什么| 花中西施指的是什么花| 勋章是什么意思| 吃什么能补肾| 混社会的人一般干什么| 萎缩性胃炎是什么意思| 六月属什么生肖| 直肠指检能检查出什么| 什么掌不能拍| 茶色是什么颜色| 老友记是什么意思| 青海有什么好玩的| 行货是什么意思| 验光是什么意思| 石膏是什么| 2月24日什么星座| 犀利什么意思| 尿酸高能吃什么肉| 右边脑袋疼是什么原因| 17数字代表什么意思| 神经性皮炎用什么药膏效果最好| 喉咙疼挂什么科| 医院建档是什么意思| 产后什么时候来月经正常| 荨麻疹是什么引起的| opv是什么疫苗| 阴毛长虱子用什么药| 老是放屁吃什么药| 扁桃体是什么| 维生素是什么| 什么齿| 什么动物最怕水| 獭尾肝是什么意思| 骑乘是什么意思| 低烧挂什么科| 吃什么补气血| 志愿号是什么意思| 脚气去医院挂什么科| 什么是认知障碍| 切糕为什么这么贵| 意下如何什么意思| 垂体催乳素高是什么原因| 自求多福什么意思| 济南为什么叫泉城| 三什么两什么| 经常吃南瓜有什么好处和坏处| 腊月十八是什么星座| 送男生什么礼物| 为什么会肾虚| 意向什么意思| 四川大学校长什么级别| 寅五行属什么| 吃什么对前列腺有好处| 福报是什么| 流鼻血是什么病的前兆| 屈光检查是什么| 陈皮配什么喝去湿气| 小资生活是什么意思| 什么是碳水食物有哪些| 所剩无几是什么意思| 心功能一级什么意思| 打胎用什么药| 血压高降不下来是什么原因| 杨梅是什么季节的水果| 女攻是什么意思| 水车是什么意思| 花字五行属什么| 逾期不候什么意思| 胃火吃什么中成药| 十二月是什么星座| 熊猫血有什么好处| 85年五行属什么| 什么是流程| 萎靡什么意思| 高血压什么症状| 吃什么能增强免疫力| 宫颈癌前期有什么症状| 女性私处痒是什么原因引起的| 炎黄子孙是什么生肖| 浮生若梦是什么意思| 孕妇缺铁性贫血对胎儿有什么影响| adhd是什么病| 严重失眠吃什么药最好| 什么药治肝最好最安全| 人为什么要穿衣服| 艾滋病英文缩写是什么| 幽门螺旋杆菌阳性代表什么| 鲁迅的原名叫什么| 肾阴虚的症状吃什么药| 什么时候放开二胎| 眼睛为什么老是流眼泪| 印度为什么没把墨脱占领| 四月十五日是什么日子| 魂牵梦萦的意思是什么| 7月22号是什么星座| 什么是月经不调| 农历7月20日是什么星座| 切除子宫对身体有什么影响| 城隍是什么意思| 中午12点到1点是什么时辰| 内敛是什么意思| 医嘱是什么意思| 什么红什么绿| 抗hp治疗是什么意思| 咳嗽挂什么科| 矽肺病是什么症状| 土是什么生肖| 什么是玄关在哪个位置| 小熊是什么牌子| 一什么露珠| 为什么女的会流水怎么回事| 鱼爱吃什么食物| 2007年是什么生肖| 什么是学前教育| dell是什么牌子的电脑| 拜复乐是什么药| 焦虑症是什么病| 吃什么| 为什么会得手足口病| abcd是什么意思| 1月3号是什么星座| 婴儿胎毛什么时候剃最好| 内分泌紊乱有什么症状表现| 衣原体检查是什么| 什么是主动脉夹层| 什么地大喊| jp是什么意思| 李子什么时候成熟| 猎户座是什么星座| 星月菩提是什么材质| 喉咙痛上火吃什么药效果最好| 龙生九子都叫什么名字| 此什么非彼什么的意思| 三月六日是什么星座| 内裤发黄是什么原因| 手心出汗是什么原因| 中暑了吃什么药| 崖柏对人体有什么好处| 吃什么都是苦的是怎么回事| 阳历7月15日是什么星座| dna是什么| 中线是什么意思| 瞒天过海是什么意思| tg是什么指标| 九月份什么星座| 心慌吃什么药| 赶集是什么意思| 四月份是什么季节| 手脚不协调是什么原因| 走读生是什么意思| 梦见买东西是什么意思| dic医学上是什么意思| 清肺吃什么好| 什么的嘴| 共襄盛举是什么意思| usc是什么意思| 解脲脲原体阳性吃什么药| 空调风扇不转是什么原因| 嗜睡乏力没精神容易疲劳是什么原因| 脖子后面长痘痘是什么原因| 绿心黑豆有什么功效| 女真族现在是什么族| 终其一生下一句是什么| 乙肝表面抗体阴性是什么意思| 大什么大| 正方形的纸能折什么| 什么食物含镁| 过敏痒用什么药膏| 急性肠胃炎是什么引起的| 皮肤过敏不能吃什么食物| 户口本可以干什么坏事| jf是什么警察| 烹饪是什么意思| 三凹征是什么| 伽马刀是什么意思| 什么的乌鸦| 阴道为什么会排气| 血糖仪什么牌子好| 静脉曲张用什么药| 作陪是什么意思| 主动权是什么意思| 嘴巴里长泡是什么原因| 为什么不| 什么情况挂全科门诊| 调理内分泌失调吃什么药效果好| 植物神经紊乱看什么科| 产后为什么脸部松弛| 惊蛰什么意思| 跟腱炎什么症状| 头眩晕看什么科| 头颈出汗多是什么原因| 风吹动窗吹动夜声响是什么歌| 百度Jump to content

章鱼属于什么类动物

From Wikibooks, open books for an open world
Previous: Classes Index Next: Interfaces
F# : Inheritance
百度 凤凰网汽车讯去年底,为了更加专注于不同领域,原德尔福汽车拆分为安波福和德尔福科技,拆分后前者专注于自动驾驶技术,而后者则致力于总成业务,继续发动机节能和新能源汽车技术的研发。

Many object-oriented languages use inheritance extensively in the .NET BCL to construct class hierarchies.

Subclasses

[edit | edit source]

A subclass is, in the simplest terms, a class derived from a class which has already been defined. A subclass inherits its members from a base class in addition to adding its own members. A subclass is defined using the inherit keyword as shown below:

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 Worker(name, employer : string) = 
    inherit Person(name)
    
    let mutable _salary = 0.0
    
    member x.Salary
        with get() = _salary
        and set value = _salary <- value
    
    member x.Employer = employer

Our simple class hierarchy looks like this:

System.Object (* All classes descend from  *)
 - Person
   - Student
   - Worker

The Student and Worker subclasses both inherit the Name and Greet methods from the Person base class. This can be demonstrated in fsi:

> let somePerson, someStudent, someWorker =
    new Person("Juliet"), new Student("Monique", 123456), new Worker("Carla", "Awesome Hair Salon");;

val someWorker : Worker
val someStudent : Student
val somePerson : Person

> somePerson.Name, someStudent.Name, someWorker.Name;;
val it : string * string * string = ("Juliet", "Monique", "Carla")

> someStudent.StudentID;;
val it : int = 123456

> someWorker.Employer;;
val it : string = "Awesome Hair Salon"

> someWorker.ToString();; (* ToString method inherited from System.Object *)
val it : string = "FSI_0002+Worker"

.NET's object model supports single-class inheritance, meaning that a subclass is limited to one base class. In other words, its not possible to create a class which derives from Student and Employee simultaneously.

Overriding Methods

[edit | edit source]

Occasionally, you may want a derived class to change the default behavior of methods inherited from the base class. For example, the output of the .ToString() method above isn't very useful. We can override that behavior with a different implementation using the override:

type Person(name) =
    member x.Name = name        
    member x.Greet() = printfn "Hi, I'm %s" x.Name
    
    override x.ToString() = x.Name    (* The ToString() method is inherited from System.Object *)

We've overridden the default implementation of the ToString() method, causing it to print out a person's name.

Methods in F# are not overridable by default. If you expect users will want to override methods in a derived class, you have to declare your method as overridable using the abstract and default keywords as follows:

type Person(name) =
    member x.Name = name        
    
    abstract Greet : unit -> unit
    default x.Greet() = printfn "Hi, I'm %s" x.Name
    
type Quebecois(name) =
    inherit Person(name)
    
    override x.Greet() = printfn "Bonjour, je m'appelle %s, eh." x.Name

Our class Person provides a Greet method which may be overridden in derived classes. Here's an example of these two classes in fsi:

> let terrance, phillip = new Person("Terrance"), new Quebecois("Phillip");;

val terrance : Person
val phillip : Quebecois

> terrance.Greet();;
Hi, I'm Terrance
val it : unit = ()

> phillip.Greet();;
Bonjour, je m'appelle Phillip, eh.

Abstract Classes

[edit | edit source]

An abstract class is one which provides an incomplete implementation of an object, and requires a programmer to create subclasses of the abstract class to fill in the rest of the implementation. For example, consider the following:

[<AbstractClass>]
type Shape(position : Point) =
    member x.Position = position
    override x.ToString() =
        sprintf "position = {%i, %i}, area = %f" position.X position.Y (x.Area())
    
    abstract member Draw : unit -> unit 
    abstract member Area : unit -> float

The first thing you'll notice is the AbstractClass attribute, which tells the compiler that our class has some abstract members. Additionally, you notice two abstract members, Draw and Area don't have an implementation, only a type signature.

We can't create an instance of Shape because the class hasn't been fully implemented. Instead, we have to derive from Shape and override the Draw and Area methods with a concrete implementation:

type Circle(position : Point, radius : float) =
    inherit Shape(position)
    
    member x.Radius = radius
    override x.Draw() = printfn "(Circle)"
    override x.Area() = Math.PI * radius * radius
    
type Rectangle(position : Point, width : float, height : float) =
    inherit Shape(position)
    
    member x.Width = width
    member x.Height = height
    override x.Draw() = printfn "(Rectangle)"
    override x.Area() = width * height
    
type Square(position : Point, width : float) =
    inherit Shape(position)
    
    member x.Width = width
    member x.ToRectangle() = new Rectangle(position, width, width)
    override x.Draw() = printfn "(Square)"
    override x.Area() = width * width
    
type Triangle(position : Point, sideA : float, sideB : float, sideC : float) =
    inherit Shape(position)
    
    member x.SideA = sideA
    member x.SideB = sideB
    member x.SideC = sideC
    
    override x.Draw() = printfn "(Triangle)"
    override x.Area() =
        (* Heron's formula *)
        let a, b, c = sideA, sideB, sideC
        let s = (a + b + c) / 2.0
        Math.Sqrt(s * (s - a) * (s - b) * (s - c) )

Now we have several different implementations of the Shape class. We can experiment with these in fsi:

> let position = { X = 0; Y = 0 };;

val position : Point

> let circle, rectangle, square, triangle =
    new Circle(position, 5.0),
    new Rectangle(position, 2.0, 7.0),
    new Square(position, 10.0),
    new Triangle(position, 3.0, 4.0, 5.0);;

val triangle : Triangle
val square : Square
val rectangle : Rectangle
val circle : Circle

> circle.ToString();;
val it : string = "Circle, position = {0, 0}, area = 78.539816"

> triangle.ToString();;
val it : string = "Triangle, position = {0, 0}, area = 6.000000"

> square.Width;;
val it : float = 10.0

> square.ToRectangle().ToString();;
val it : string = "Rectangle, position = {0, 0}, area = 100.000000"

> rectangle.Height, rectangle.Width;;
val it : float * float = (7.0, 2.0)

Working With Subclasses

[edit | edit source]

Up-casting and Down-casting

[edit | edit source]

A type cast is an operation which changes the type of an object from one type to another. This is not the same as a map function, because a type cast does not return an instance of a new object, it returns the same instance of an object with a different type.

For example, let's say B is a subclass of A. If we have an instance of B, we are able to cast as an instance of A. Since A is upward in the class hierarchy, we call this an up-cast. We use the :> operator to perform upcasts:

> let regularString = "Hello world";;

val regularString : string

> let upcastString = "Hello world" :> obj;;

val upcastString : obj

> regularString.ToString();;
val it : string = "Hello world"

> regularString.Length;;
val it : int = 11

> upcastString.ToString();; (* type obj has a .ToString method *)
val it : string = "Hello world"

> upcastString.Length;; (* however, obj does not have Length method *)

  upcastString.Length;; (* however, obj does not have Length method *)
  -------------^^^^^^^

stdin(24,14): error FS0039: The field, constructor or member 'Length' is not defined.

Up-casting is considered "safe", because a derived class is guaranteed to have all of the same members as an ancestor class. We can, if necessary, go in the opposite direction: we can down-cast from an ancestor class to a derived class using the :?> operator:

> let intAsObj = 20 :> obj;;

val intAsObj : obj

> intAsObj, intAsObj.ToString();;
val it : obj * string = (20, "20")

> let intDownCast = intAsObj :?> int;;

val intDownCast : int

> intDownCast, intDownCast.ToString();;
val it : int * string = (20, "20")

> let stringDownCast = intAsObj :?> string;; (* boom! *)

val stringDownCast : string

System.InvalidCastException: Unable to cast object of type 'System.Int32' to type 'System.String'.
   at <StartupCode$FSI_0067>.$FSI_0067._main()
stopped due to error

Since intAsObj holds an int boxed as an obj, we can downcast to an int as needed. However, we cannot downcast to a string because it is an incompatible type. Down-casting is considered "unsafe" because the error isn't detectable by the type-checker, so an error with a down-cast always results in a runtime exception.

Up-casting example

[edit | edit source]
open System

type Point = { X : int; Y : int }

[<AbstractClass>]
type Shape() =
    override x.ToString() =
        sprintf "%s, area = %f" (x.GetType().Name) (x.Area())
    
    abstract member Draw : unit -> unit 
    abstract member Area : unit -> float
    
type Circle(radius : float) =
    inherit Shape()
    
    member x.Radius = radius
    override x.Draw() = printfn "(Circle)"
    override x.Area() = Math.PI * radius * radius
    
type Rectangle(width : float, height : float) =
    inherit Shape()
    
    member x.Width = width
    member x.Height = height
    override x.Draw() = printfn "(Rectangle)"
    override x.Area() = width * height
    
type Square(width : float) =
    inherit Shape()
    
    member x.Width = width
    member x.ToRectangle() = new Rectangle(width, width)
    override x.Draw() = printfn "(Square)"
    override x.Area() = width * width
    
type Triangle(sideA : float, sideB : float, sideC : float) =
    inherit Shape()
    
    member x.SideA = sideA
    member x.SideB = sideB
    member x.SideC = sideC
    
    override x.Draw() = printfn "(Triangle)"
    override x.Area() =
        (* Heron's formula *)
        let a, b, c = sideA, sideB, sideC
        let s = (a + b + c) / 2.0
        Math.Sqrt(s * (s - a) * (s - b) * (s - c) )

let shapes =
        [(new Circle(5.0) :> Shape);
            (new Circle(12.0) :> Shape);
            (new Square(10.5) :> Shape);
            (new Triangle(3.0, 4.0, 5.0) :> Shape);
            (new Rectangle(5.0, 2.0) :> Shape)]
        (* Notice we have to cast each object as a Shape *)
            
let main() = 
    shapes
    |> Seq.iter (fun x -> printfn "x.ToString: %s" (x.ToString()) )

main()

This program has the following types:

type Point =
  {X: int;
   Y: int;}

type Shape =
  class
    abstract member Area : unit -> float
    abstract member Draw : unit -> unit
    new : unit -> Shape
    override ToString : unit -> string
  end

type Circle =
  class
    inherit Shape
    new : radius:float -> Circle
    override Area : unit -> float
    override Draw : unit -> unit
    member Radius : float
  end

type Rectangle =
  class
    inherit Shape
    new : width:float * height:float -> Rectangle
    override Area : unit -> float
    override Draw : unit -> unit
    member Height : float
    member Width : float
  end

type Square =
  class
    inherit Shape
    new : width:float -> Square
    override Area : unit -> float
    override Draw : unit -> unit
    member ToRectangle : unit -> Rectangle
    member Width : float
  end

type Triangle =
  class
    inherit Shape
    new : sideA:float * sideB:float * sideC:float -> Triangle
    override Area : unit -> float
    override Draw : unit -> unit
    member SideA : float
    member SideB : float
    member SideC : float
  end

val shapes : Shape list

This program outputs:

x.ToString: Circle, area = 78.539816
x.ToString: Circle, area = 452.389342
x.ToString: Square, area = 110.250000
x.ToString: Triangle, area = 6.000000
x.ToString: Rectangle, area = 10.000000

Public, Private, and Protected Members

[edit | edit source]
Previous: Classes Index Next: Interfaces
外阴苔藓用什么药膏 自古红颜多薄命是什么意思 十月十二号是什么星座 94年什么命 强直性脊柱炎是什么病
拔罐对身体有什么好处 伏羲是什么意思 b3维生素又叫什么 下水是什么意思 左舌根疼痛是什么情况
甘油三酯什么意思 螃蟹为什么横着走 韭菜不能和什么一起吃 猫咪有泪痕是什么原因 UDCA是什么药
杨梅不能和什么一起吃 流清水鼻涕吃什么药 什么叫淋巴结转移 sjh是什么意思 praal00是什么型号
属羊的跟什么属相犯冲jingluanji.com sherpa是什么面料hcv9jop2ns4r.cn nh3是什么hcv9jop5ns7r.cn 脚踝肿是什么原因bfb118.com 铁观音是属于什么茶hcv9jop2ns2r.cn
霉菌性阴道炎是什么引起的hcv8jop3ns2r.cn 来月经喝红糖水有什么好处hcv8jop3ns3r.cn 紫涵女装属于什么档次hcv9jop0ns3r.cn 寡妇年是什么意思hcv9jop2ns9r.cn 晚上睡觉尿多是什么原因hcv8jop9ns8r.cn
金鱼吊兰什么时候开花hcv8jop4ns9r.cn 蒙古国什么时候独立的helloaicloud.com 柱镜是什么hcv7jop6ns9r.cn 怀孕第一个月吃什么对胎儿好hcv7jop6ns1r.cn 女人切除子宫有什么影响hcv7jop5ns0r.cn
文殊菩萨保佑什么hcv9jop5ns0r.cn 这是什么表情包hcv9jop7ns5r.cn 腰椎痛用什么药hcv8jop7ns8r.cn 狗为什么喜欢吃屎hcv9jop0ns1r.cn 半月板损伤吃什么药hcv9jop3ns1r.cn
百度