c#和php中抽象类实现的差异
我使用PHP已经有一段时间了,现在我正在尝试探索c#的世界。我试图理解c#sharp中的抽象类实现。我发现两种语言的行为都有一些波动。这就是为什么我在这里发布它,以便更好地了解c#中的抽象类实现 PHP和C#都扩展了抽象类。这意味着所有从抽象类扩展的类都必须实现抽象方法,并从抽象类继承非抽象公共方法 从抽象类的方法访问子类的属性时会出现问题。在PHP中,可以访问公共头发属性。但是在C#c#和php中抽象类实现的差异,c#,php,oop,inheritance,abstract-class,C#,Php,Oop,Inheritance,Abstract Class,我使用PHP已经有一段时间了,现在我正在尝试探索c#的世界。我试图理解c#sharp中的抽象类实现。我发现两种语言的行为都有一些波动。这就是为什么我在这里发布它,以便更好地了解c#中的抽象类实现 PHP和C#都扩展了抽象类。这意味着所有从抽象类扩展的类都必须实现抽象方法,并从抽象类继承非抽象公共方法 从抽象类的方法访问子类的属性时会出现问题。在PHP中,可以访问公共头发属性。但是在C#getHairColor()中,无法访问从抽象类扩展而来的类的公共hair属性 我认为,当男性类扩展Person
getHairColor()
中,无法访问从抽象类扩展而来的类的公共hair属性
我认为,当男性类扩展Person类时,它还从父类继承了getHairColor()
方法。在这里,PHP实现比C#更有意义。我能用两种不同的语言对一个相似概念的不同行为做出正确的解释吗
PHP:
abstract class Person{
abstract public function setHairColor($color);
public function getHairColor(){
return $this->hair; // $this->hair is accessible from here
}
}
class Male extends Person{
public $hair;
public function setHairColor($color){
$this->hair = $color;
}
}
$male1 = new Male();
$male1->setHairColor("black");
echo $male1->getHairColor(); // access hair property
abstract class Person
{
public abstract void setHairColor(string hair);
public string getHairColor()
{
return this.hair; // this.hair is not accessible from here
}
}
class Male : Person
{
public string hair;
public override void setHairColor(string hair)
{
this.hair = hair;
}
}
Male male1 = new Male();
male1.setHairColor("black");
Console.WriteLine(male1.getHairColor()); // can not access hair property
C#:
abstract class Person{
abstract public function setHairColor($color);
public function getHairColor(){
return $this->hair; // $this->hair is accessible from here
}
}
class Male extends Person{
public $hair;
public function setHairColor($color){
$this->hair = $color;
}
}
$male1 = new Male();
$male1->setHairColor("black");
echo $male1->getHairColor(); // access hair property
abstract class Person
{
public abstract void setHairColor(string hair);
public string getHairColor()
{
return this.hair; // this.hair is not accessible from here
}
}
class Male : Person
{
public string hair;
public override void setHairColor(string hair)
{
this.hair = hair;
}
}
Male male1 = new Male();
male1.setHairColor("black");
Console.WriteLine(male1.getHairColor()); // can not access hair property
C#具有静态类型。这就是为什么不能访问在子类中声明的字段或属性。您必须在Person
中将Hair
声明为抽象属性,并在子类中实现它:
abstract class Person
{
public abstract void SetHairColor(string hair);
public abstract string Hair { get; }
public string getHairColor()
{
return this.Hair; // now it is accessible
}
}
class Male : Person
{
private string _Hair;
public override string Hair { get { return _Hair; } }
public override void SetHairColor(string hair)
{
this._Hair = hair;
}
}
您还可以将SetHairColor
实现为属性Hair
的setter:
abstract class Person
{
public abstract string Hair { get; set; }
public string getHairColor()
{
return this.Hair; // now it is accessible
}
}
class Male : Person
{
private string _Hair;
public override string Hair
{
get { return _Hair; }
set { _Hair = value }
}
}
否,无法从父级访问在子级中定义的属性。如果所有
Person
都有头发,为什么不在Person
中定义hair
?如果扩展Person
而不定义hair
,PHP中会发生什么?但它是从抽象类扩展而来的。因此getHairColor是子类的继承方法。这就是为什么我认为它应该访问hair属性。所以,关于抽象类概念的实现,哪种语言更符合逻辑。为什么你的(抽象)基类知道它的子类?如果你觉得这是合乎逻辑的,你是说如果我实现了Dog:Animal
,一只Dog
可以吠叫,那么突然之间,我可以让所有Animal.bark()
,就因为我定义了bark()代码>在其子代之一中。感谢您的回复。您提到了术语静态键入。但是你能解释一下静态类型化对这种行为有什么作用吗?对于术语静态类型化的一般解释,你可以研究一下:,或者这个:C#只接受那些可以在编译时解析的引用。如果抽象类中没有声明字段hair
,编译器如何知道所有可能的子类中都有字段hair
?您可能在某个地方定义了一个子类BaldHead
,它没有字段hair
。但是在Person
中声明一个抽象属性Hair
,可以确保所有子类都实现这样一个属性。在使用动态键入的语言中,这将在运行时进行检查,如果您试图访问秃头的头发,则会出现运行时错误。