父类方法

# encoding: utf-8

class Animal(object):
    """docstring for Animal"""
    def __init__(self, name, age):
        super(Animal, self).__init__()
        print 'animal __init__'
        self.name = name
        self.age = age

    def move(self):
        print 'animal move'
        
class Cat(Animal):
    
    def __init__(self, name, age):
        super(Animal, self).__init__()
        print 'cat __init__'


    def move(self):
        super(Cat, self).move()  # 调用父类方法
        print 'cat move'


a = Animal('nn', 4)

a.move()


c = Cat('c', 5)
c.move()

 

<think>在C#中,子类调用父类方法主要有以下几种方式: 1. 直接调用(当子类没有重父类方法时) 2. 使用`base`关键字(当子类重父类方法,但需要调用父类版本时) 3. 通过构造函数调用(在子类构造函数中调用父类构造函数) 下面将详细解释并给出代码示例。 ### 1. 直接调用父类方法 当子类没有重父类方法时,可以直接通过子类实例调用继承自父类方法。 ```csharp public class Parent { public void ParentMethod() { Console.WriteLine("父类方法"); } } public class Child : Parent { // 子类没有重ParentMethod,所以直接继承 } // 使用 Child child = new Child(); child.ParentMethod(); // 输出:父类方法 ``` ### 2. 使用`base`关键字调用父类方法 当子类重父类方法,但希望在子类方法中调用父类的原始方法时,可以使用`base`关键字。 ```csharp public class Parent { public virtual void Method() // 使用virtual关键字允许子类重 { Console.WriteLine("父类方法"); } } public class Child : Parent { public override void Method() // 重父类方法 { // 先调用父类方法 base.Method(); // 输出:父类方法 Console.WriteLine("子类方法"); } } // 使用 Child child = new Child(); child.Method(); // 输出:父类方法\n子类方法 ``` ### 3. 在构造函数中调用父类构造函数 子类构造函数可以通过`base`关键字调用父类的构造函数,确保父类部分正确初始化。 ```csharp public class Parent { protected string _name; public Parent(string name) { _name = name; Console.WriteLine("父类构造函数"); } } public class Child : Parent { public Child(string name) : base(name) // 调用父类构造函数 { Console.WriteLine("子类构造函数"); } } // 使用 Child child = new Child("小明"); // 输出:父类构造函数\n子类构造函数 ``` ### 4. 模板方法模式(通过抽象方法强制子类实现,但由父类控制流程) 父类定义一个公共方法(可包含一些固定步骤),其中调用一个抽象方法,子类必须实现该抽象方法。这样在调用公共方法时,父类逻辑和子类实现都会执行。 ```csharp public abstract class Parent { public void TemplateMethod() { Console.WriteLine("父类固定步骤"); AbstractMethod(); // 调用子类实现的抽象方法 } protected abstract void AbstractMethod(); } public class Child : Parent { protected override void AbstractMethod() { Console.WriteLine("子类实现的方法"); } } // 使用 Parent instance = new Child(); instance.TemplateMethod(); // 输出:父类固定步骤\n子类实现的方法 ``` ### 注意事项: - **方法可见性**:父类方法需要是`public`、`protected`或`internal`(同一程序集内)才能被子类访问。 - **虚方法**:如果希望子类可以重方法父类方法必须标记为`virtual`(或`abstract`,如果是抽象方法)。 - **密封方法**:如果父类方法使用`sealed`关键字(通常与`override`一起使用),则子类不能重方法。 ### 引用说明: - 在构造函数中调用父类构造函数(如示例3)符合引用[2]和[3]的描述,即使用`base`关键字并放在子类构造函数参数后[^2][^3]。 - 使用`base`关键字调用父类方法(如示例2)在引用[1]中也有体现(虽然引用[1]是Python代码,但概念相似)[^1]。 - 模板方法模式(如示例4)对应引用[4]的内容,父类控制流程,子类实现具体步骤[^4]。 ### 完整示例代码 ```csharp using System; public class Parent { public virtual void CommonMethod() { Console.WriteLine("父类的CommonMethod"); } public Parent(string name) { Console.WriteLine($"父类构造函数,参数:{name}"); } } public class Child : Parent { public Child(string name) : base(name) // 调用父类构造函数 { Console.WriteLine("子类构造函数"); } public override void CommonMethod() { base.CommonMethod(); // 调用父类方法 Console.WriteLine("子类添加的行为"); } } // 测试 class Program { static void Main() { Child child = new Child("小明"); child.CommonMethod(); } } ``` 输出: ``` 父类构造函数,参数:小明 子类构造函数 父类的CommonMethod 子类添加的行为 ``` ### 相关问题 1. C#中如何阻止子类重父类方法? 2. 在C#中,子类调用父类的私有方法有哪些方式? 3. 如何通过反射在子类中调用父类方法? 4. C#的抽象类与接口在方法调用上有何异同?</think>在C#中,子类调用父类方法主要有以下几种方式,这些方法都基于面向对象的继承机制: ### 1. **直接调用(未重时)** 当子类**没有重**父类方法时,可以直接通过子类实例调用继承的方法: ```csharp public class Parent { public void ParentMethod() { Console.WriteLine("父类方法"); } } public class Child : Parent { /* 未重ParentMethod */ } // 使用 Child child = new Child(); child.ParentMethod(); // 直接调用父类方法 ``` ### 2. **使用`base`关键字(重时调用父类版本)** 当子类重父类方法,但仍需调用父类原始实现时,使用`base`关键字: ```csharp public class Parent { public virtual void CommonMethod() // 需标记为virtual { Console.WriteLine("父类原始方法"); } } public class Child : Parent { public override void CommonMethod() { base.CommonMethod(); // 调用父类版本 Console.WriteLine("子类新增逻辑"); } } // 使用 Child child = new Child(); child.CommonMethod(); // 输出: // 父类原始方法 // 子类新增逻辑 ``` ### 3. **在构造函数中调用父类构造函数** 子类构造函数通过`: base()`调用父类构造函数(必须作为第一条语句): ```csharp public class Parent { protected string _name; public Parent(string name) { _name = name; Console.WriteLine($"父类初始化: {_name}"); } } public class Child : Parent { public Child(string name, int age) : base(name) // 调用父类构造 { Console.WriteLine($"子类初始化: {age}岁"); } } // 使用 var child = new Child("小明", 10); // 输出: // 父类初始化: 小明 // 子类初始化: 10岁 ``` ### 4. **模板方法模式(父类控制流程)** 父类定义算法骨架,子类实现具体步骤(通过`abstract`或`virtual`方法): ```csharp public abstract class Parent { public void TemplateMethod() // 公共模板方法 { Console.WriteLine("固定步骤1"); CustomStep(); // 调用子类实现 Console.WriteLine("固定步骤2"); } protected abstract void CustomStep(); // 子类必须实现 } public class Child : Parent { protected override void CustomStep() { Console.WriteLine("子类自定义步骤"); } } // 使用 Parent obj = new Child(); obj.TemplateMethod(); // 输出: // 固定步骤1 // 子类自定义步骤 // 固定步骤2 ``` ### 关键注意事项 1. **方法可见性**: - 父类方法需为 `public`/`protected`(`private`方法不可被子类调用) - 需重时标记为 `virtual` 或 `abstract` 2. **构造函数规则**: - 子类构造函数必须通过`: base(...)`显式或隐式调用父类构造函数[^2][^3] - 若父类有无参构造函数,子类可不显式调用(编译器自动添加) 3. **`base`使用场景**: - 主要用于解决子类重方法后仍需访问父类实现的场景 - 不能用于静态方法(静态方法不属于实例) > 引用说明: > - 直接调用和`base`关键字对应引用[1]中Python示例的C#实现[^1] > - 构造函数调用规则符合引用[2][3]描述的C#/Java规范[^2][^3] > - 模板方法模式参考引用[4]的设计[^4] ### 完整示例 ```csharp using System; public class Vehicle // 父类 { protected string _model; public Vehicle(string model) { _model = model; } public virtual void StartEngine() { Console.WriteLine($"{_model} 引擎启动"); } } public class Car : Vehicle // 子类 { public Car(string model) : base(model) { } public override void StartEngine() { base.StartEngine(); // 调用父类方法 Console.WriteLine("车载系统初始化完成"); } public void ShowInfo() { Console.WriteLine($"车型: {_model}"); // 访问父类属性 } } class Program { static void Main() { Car myCar = new Car("特斯拉Model3"); myCar.StartEngine(); myCar.ShowInfo(); } } ``` 输出: ``` 特斯拉Model3 引擎启动 车载系统初始化完成 车型: 特斯拉Model3 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值