Animal objDog = new Dog()和 Dog objDog = new Dog()的区别
文章目录
- 1、Animal objDog = new Dog()和 Dog objDog = new Dog()的区别
- 1. **对象类型(引用类型)**
- 2. **调用和可用成员**
- 3. **示例代码来说明**
- 使用示例
- 总结
- 2、Animal objDog = new Dog();不能调用dog的方法和属性是为什么?
- 原因解析
- 解决方法
- 小结
1、Animal objDog = new Dog()和 Dog objDog = new Dog()的区别
在 C# 语言中,Animal objDog = new Dog("棒棒", "黑色", "小黑狗", "排骨");
和 Dog objDog = new Dog("棒棒", "黑色", "小黑狗", "排骨");
的区别主要体现在对象的类型(引用类型)和可用的成员(方法、属性)。具体来看:
1. 对象类型(引用类型)
-
Animal objDog = new Dog(...)
:- 这里,
objDog
是一个父类Animal
类型的引用,指向了一个Dog
类型的实例。 - 因为
objDog
的类型是Animal
,你只能访问在Animal
类中定义的方法和属性(包括虚拟方法)。 - 你可以通过
objDog
调用Animal
中的虚拟方法(如果有重写),但不能直接访问Dog
类中特有的方法和属性(如果没有显式转换)。
- 这里,
-
Dog objDog = new Dog(...)
:- 这里,
objDog
是Dog
类型的引用,指向的是一个Dog
的实例。 - 可以访问
Dog
类中所有的方法和属性,包括父类Animal
中的方法(因为Dog
继承自Animal
)。
- 这里,
2. 调用和可用成员
-
使用
Animal
类型引用:- 只能调用
Animal
中的成员,且如果Animal
中有虚拟方法并在Dog
中重写了,实际调用时会执行Dog
中重写的方法。 - 例如,如果
Animal
类有一个虚拟方法Speak()
,你可以这样调用:objDog.Speak(); // 如果在 Dog 中重写了 Speak() 方法,会调用 Dog 的实现。
- 只能调用
-
使用
Dog
类型引用:- 可以直接调用
Dog
中的所有方法和属性,包括Animal
类定义的成员。 - 例如:
objDog.Bark(); // 直接调用 Dog 类特有的方法
- 可以直接调用
3. 示例代码来说明
假设我们有如下类定义:
public class Animal
{
public string Name { get; set; }
public string Color { get; set; }
public Animal(string name, string color)
{
Name = name;
Color = color;
}
public virtual void Speak()
{
Console.WriteLine($"{Name} speaks!");
}
}
public class Dog : Animal
{
public string Breed { get; set; }
public string FavoriteFood { get; set; }
public Dog(string name, string color, string breed, string favoriteFood)
: base(name, color)
{
Breed = breed;
FavoriteFood = favoriteFood;
}
public override void Speak()
{
Console.WriteLine($"{Name} (a {Breed}) barks!");
}
public void Bark()
{
Console.WriteLine($"{Name} is barking!");
}
}
使用示例
Animal objDog1 = new Dog("棒棒", "黑色", "小黑狗", "排骨");
objDog1.Speak(); // 输出: 棒棒 (a 小黑狗) barks!
objDog1.Bark(); // 编译错误: objDog1没有Bark方法
Dog objDog2 = new Dog("棒棒", "黑色", "小黑狗", "排骨");
objDog2.Speak(); // 输出: 棒棒 (a 小黑狗) barks!
objDog2.Bark(); // 输出: 棒棒 is barking!
总结
- 使用父类类型的引用(
Animal objDog
)可以提高程序的灵活性,适合处理多态性,但访问成员的限制较多。 - 使用子类类型的引用(
Dog objDog
)允许你访问所有相关成员,适合需要直接使用子类特有功能的场景。
2、Animal objDog = new Dog();不能调用dog的方法和属性是为什么?
在 C# 中,Animal objDog = new Dog();
这行代码的主要作用是将一个 Dog
对象赋值给一个 Animal
类型的引用变量 objDog
。虽然 objDog
实际上引用的是一个 Dog
对象,但由于它的类型是 Animal
,你只能访问 Animal
类中定义的方法和属性,而不能调用 Dog
类中特有的方法和属性。
原因解析
-
类型限制:
objDog
被声明为Animal
类型,因此编译器只允许你访问Animal
类中定义的 public 和 protected 方法和属性。- 即使它在运行时指向一个
Dog
对象,编译器并不知道,除非你将其转换为Dog
类型。
-
方法和属性的可见性:
- 如果
Dog
类中有只在Dog
类中定义的方法或属性(如Bark()
),这些方法和属性在Animal
类中是不可见的,因此你无法直接通过objDog
调用它们。
- 如果
解决方法
如果你需要调用 Dog
类中特有的方法和属性,可以将 objDog
类型转换为 Dog
,如下面的代码示例所示:
public class Animal
{
public string Name { get; set; }
public string Color { get; set; }
public Animal(string name, string color)
{
Name = name;
Color = color;
}
public virtual void Speak()
{
Console.WriteLine($"{Name} speaks!");
}
}
public class Dog : Animal
{
public string Breed { get; set; }
public string FavoriteFood { get; set; }
public Dog(string name, string color, string breed, string favoriteFood)
: base(name, color)
{
Breed = breed;
FavoriteFood = favoriteFood;
}
public override void Speak()
{
Console.WriteLine($"{Name} (a {Breed}) barks!");
}
public void Bark()
{
Console.WriteLine($"{Name} is barking!");
}
}
// 使用示例
Animal objDog = new Dog("棒棒", "黑色", "小黑狗", "排骨");
// objDog.Bark(); // 编译错误,因为 Animal 类型没有 Bark 方法
// 类型转换
if (objDog is Dog dog)
{
dog.Bark(); // 正确调用 Dog 类中特有的方法
}
小结
- 使用
Animal objDog = new Dog();
时,objDog
的类型是Animal
,只能使用Animal
中定义的方法和属性。 - 若想使用
Dog
类中特有的方法和属性,需要将其转换为Dog
类型。这可以通过is
关键字或显式转换来实现。