Oop 关于“的问题”;铸造操作“;面向对象
编程时,我们通常使用一些类型转换操作 当施法发生在“同一水平”的物体上时,感觉还可以。但当它发生在“不同层次”(主要是父子之间)的项目上时,感觉很奇怪 考虑到这一点:Oop 关于“的问题”;铸造操作“;面向对象,oop,Oop,编程时,我们通常使用一些类型转换操作 当施法发生在“同一水平”的物体上时,感觉还可以。但当它发生在“不同层次”(主要是父子之间)的项目上时,感觉很奇怪 考虑到这一点: Class Son extends Father 当儿子s=(儿子)父亲时,这绝对不合理。因为“儿子”不再是“父亲”,所以“儿子”长大后可能会有一些“父亲”没有的新属性,铸造操作使这些属性变得未知 另一方面,父亲f=(父亲)儿子似乎合理,但根据 “派生类的实例应能够替换其超类的任何实例” 一个“儿子”可以做他“父亲”能做的任何事
Class Son extends Father
当<代码>儿子s=(儿子)父亲时代码>,这绝对不合理。因为“儿子”不再是“父亲”,所以“儿子”长大后可能会有一些“父亲”没有的新属性,铸造操作使这些属性变得未知
另一方面,父亲f=(父亲)儿子
似乎合理,但根据
“派生类的实例应能够替换其超类的任何实例”
一个“儿子”可以做他“父亲”能做的任何事情,所以演员的操作似乎是无用的
那么,我能说这些铸造操作不是基于OO设计原则,而是必要的吗?我发现这些问题总是很有趣,我认为这会引发某种争论:) 这是我的想法。 在类设计中,在这种情况下,我将创建一个Person类
class Person
{
public bool IsFather { get; set; } // this variable will change depending on the count of children
public List<Person> children { get; set; }
}
班级人员
{
public bool IsFather{get;set;}//此变量将根据子项的计数而更改
公共列表子项{get;set;}
}
当我创建一个派生类时,该类应该是一个专门的人,对于父子类,我不会创建父子类。在OOP中转换对象通常是类继承或接口继承的产物。必须始终记住,类继承表示“是一个”关系,接口继承表示“有一个”关系 让我们来看一下您的示例:
类儿子扩展了父亲
听起来并不是一个合理的抽象概念,因为每个男性都是儿子,但并非所有男性都是父亲。事实上,相反的情况可能更适用:类父扩展了子
,因为每个父亲都是某个人的儿子
另一方面,我们可以抛开这个抽象概念,说我们有一个类人
,可以是男性或女性,也可以是母亲或父亲,等等。每个人都有一个属性,该属性包含名为子项的人
的集合
在这个抽象概念中,一个人
只有在其性别为男性且Person.Children.Count>0时才会被视为父亲
。这比单独定义父类要简单得多。对我来说都不合理。似乎更有道理的是:
Son s = (Son)person //Valid
Father f = (Father)person //Valid
你继承遗产的例子很糟糕
更好的可能是
Class Person
{
public void walk();
}
Class Man extends Person
{
public void shaveBeard();
}
继承是表示关系的方式;e、 g.“一个人
是一个人
”
使用对象
这两行都可以
Person p = new Person();
Person m = new Man();
在这两种情况下都可以调用p.walk
。但是,要调用shavebeard()
方法,m
必须是Man
对象。出于类型安全的原因,您必须将其强制转换为Man
对象;e、 g.(男)m.shaveBeard()代码>此处的强制转换将失败,因此最好检查变量是否引用了Man
的实例:
if(m instanceof Man)
{
(Man) m.shaveBeard();
}
这里有一个提示:左侧的类是超类,右侧的类是子类,因此如果我们有以下内容:
对象p=新学生()//是正确的
Student s=new Object()//是错误的……就像说每个对象都是学生一样。。
在进行显式转换时必须小心,因为它可能看起来正确,但可能无法按预期工作。你不能把你父亲的私人财产给你自己。我想我们的想法是一样的:)我只是忘记了性别,愚蠢的性别:p