继承和多态举例

程序1

需求:建立一个人类(Person)和学生类(Student)功能如下:

1)Person包含4个数据成员name、addr、gender和age,分别表示姓名、地址、类别和年龄。设计一个输出方法talk()来显示这4个属性。

2)Student类继承Person类,并增加成员Math和English来存放数学和英语成绩,用一个6参数构造方法、一个2参数构造方法、一个无参构造方法和覆写输出方法talk()用于显示6种属性。对于构造方法参数个数不足以初始化数据成员的,在构造方法中采用自己指定默认值来实施初始化。

package com.liaojianya.chapter2;
/**
 * This program demonstrates the use of polymorphisn.
 * @author LIAO JIANYA
 * 2016年7月24日
 */
public class PersonStudent
{
	public static void main(String[] args)
	{
		Person p = new Student("王二", "上海", "female", 44, 100, 53);
		System.out.println(p.talk());
		Person p1 = new Student(55, 66);
		System.out.println(p1.talk());
		Person p2 = new Student();
		System.out.println(p2.talk());
	}

}
class Person
{
	String name;
	String addr;
	String gender;
	int age;
	public Person()
	{
		
	}
	public Person(String name, String addr, String gender, int age)
	{
		this.name = name;
		this.addr = addr;
		this.gender = gender;
		this.age = age;
	}
	public String talk()
	{
		return "My name is " + name + ", address is "
				+ addr + ", my gender is " + gender + ", I'm " + age + " years old.";
	}
	
}

class Student extends Person
{
	float Math;
	float English;
	public Student(String name, String addr, String gender, int age, float Math, float English)
	{
		super(name, addr, gender, age);
		this.Math = Math;
		this.English = English;
				
	}
	public Student(float Math, float English)
	{
		this.name = "wangyuan";
		this.addr = "nanjing";
		this.gender = "male";
		this.age = 33;
		this.Math = Math;
		this.English = English;
		
	}
	public Student()
	{
		this.name = "王小元";
		this.addr = "南京";
		this.gender = "男";
		this.age = 23;
		this.Math = 98.5f;
		this.English = 56.6f;
	}
	public String talk()
	{
		return super.talk() + "My Math score is " + Math + ", and my English score is " +English;
	}
	
}

  运行结果:

My name is 王二, address is 上海, my gender is female, I'm 44 years old.My Math score is 100.0, and my English score is 53.0
My name is wangyuan, address is nanjing, my gender is male, I'm 33 years old.My Math score is 55.0, and my English score is 66.0
My name is 王小元, address is 南京, my gender is 男, I'm 23 years old.My Math score is 98.5, and my English score is 56.6

  程序2:

package com.liaojianya.chapter2;
/**
 * 定义一个Instrument乐器类,并定义其公有的方法play(),再分别定义其子类Wind(管乐器)
 * Percussion(打击乐器),Stringed(弦乐器),覆写play方法,实现每种乐器独有的play方式。
 * 最后在测试类中使用多态的方法执行每个子类的play()方法。
 * @author LIAO JIANYA
 * 2016年7月24日
 */
public class InstrumentTest
{
	public static void main(String[] args)
	{
		Instrument ins;
		Wind w = new Wind();
		ins = w;
		ins.play();
		Percussion p = new Percussion();
		ins = p;
		ins.play();
		Stringed s = new Stringed();
		ins = s;
		ins.play();
		
	}
}

class Instrument
{
	public void play()
	{
		System.out.println("乐器演奏!");
	}
}

class Wind extends Instrument
{
	public void play()
	{
		System.out.println("管乐器演奏!");
	}
}

class Percussion extends Instrument
{
	public void play()
	{
		System.out.println("打击乐器演奏 !");
	}
}

class Stringed extends Instrument
{
	public void play()
	{
		System.out.println("弦乐器演奏!");
	}
}

  运行结果:

管乐器演奏!
打击乐器演奏 !
弦乐器演奏!

  分析:

  1)通过赋值操作,将这些子类乐器对象向上类型转换为Instrument类型,然后经过父类对象ins调用其play方法,这时,实际调用的是各个子类对象的play方法。

  2)父类对象依据被赋值的每个子类对象的类型,做出恰当的相应(即与对象具体类别相适应的反应),这就是对象多态性的关键思想。同样的消息或者接口(本例中都是play)在发送给不同的对象时,会产生多种形式的结果。

  3)继承是子类使用父类的方法,多态则是父类使用子类的方法。确切的说,多态是父类使用被子类覆盖的同名方法,如果子类的方法是全新的,父类不存在同名的方法,则父类也不能使用子类自己独有的方法。

转载于:https://www.cnblogs.com/Andya/p/5700138.html

<think>嗯,用户想了解C++中的继承多态接口相关的用法,特别是实现使用教程。首先,我需要回忆一下C++的这些概念。继承是面向对象编程中的一个核心概念,允许子类继承父类的属性方法。多态则是通过虚函数实现的,使得不同子类对象可以对同一方法有不同的实现。接口在C++中通常通过纯虚函数抽象类来实现,类似于Java中的接口。 用户提供的三个引用里提到了一些关键点。引用1提到多态性允许根据对象实际类型调用不同函数版本,这涉及到虚函数表动态绑定。引用2给出了一个具体的代码示例,展示了基类A1派生类B1、C1中的虚函数重写。引用3指出子类可以拥有父类的非私有属性方法,并可以扩展或重写它们。 用户可能需要一个结构化的教程,涵盖基本概念、语法、接口实现方法以及实际应用示例。首先应该解释继承的基本用法,比如公有继承、保护继承私有继承的区别,但通常主要使用公有继承。然后是多态,需要详细说明虚函数的作用,以及如何通过基类指针或引用调用派生类的方法。接口的实现部分需要介绍纯虚函数抽象类,因为C++没有专门的接口关键字,但可以通过纯虚类模拟接口。 接下来要考虑用户可能的疑问点。例如,虚函数表的工作原理,这在引用12中都有涉及,可能需要简要解释。另外,构造函数析构函数在继承中的注意事项,特别是虚析构函数的重要性,避免资源泄漏。还有overridefinal关键字的用法,这些C++11引入的特性可以帮助避免错误,提高代码可读性。 实际应用场景方面,可以举例说明多态在框架设计中的用途,比如插件系统或GUI事件处理,这些地方需要统一的接口但不同的实现。性能方面,可能需要提到虚函数调用会有一定的开销,但通常可以忽略,除非在极端性能敏感的场景。 最后,生成相关问题时,需要考虑用户可能进一步想知道的内容,比如虚函数表的具体结构,多态的性能影响,设计模式中的应用,以及如何避免常见的陷阱如对象切片等。这些问题可以帮助用户深入理解并正确应用这些概念。</think>### C++继承多态详解:接口实现与应用 #### 一、继承基础 1. **核心概念** - 子类继承父类非`private`成员属性方法[^3] - 继承类型:`public`/`protected`/`private`(常用`public`) - 代码示例: ```cpp class Animal { public: void eat() { cout << "Eating" << endl; } }; class Cat : public Animal { public: void meow() { cout << "Meow!" << endl; } }; ``` 2. **内存结构** 子类对象包含父类子对象,内存布局为:父类成员在前,子类新增成员在后[^1] #### 二、多态实现 1. **虚函数机制** - 虚函数声明:`virtual void func()` - 虚函数表(vtable)存储函数指针 - 代码示例: ```cpp class Shape { public: virtual void draw() = 0; // 纯虚函数 virtual ~Shape() {} // 虚析构函数 }; class Circle : public Shape { public: void draw() override { cout << "Drawing circle" << endl; } }; ``` 2. **多态调用** 通过基类指针/引用实现动态绑定: ```cpp Shape* shape = new Circle(); shape->draw(); // 输出"Drawing circle" delete shape; ``` #### 三、接口实现 C++通过纯虚函数实现接口: ```cpp class IPrintable { public: virtual void print() const = 0; virtual ~IPrintable() = default; }; class Document : public IPrintable { public: void print() const override { cout << "Printing document" << endl; } }; ``` #### 四、关键实践技巧 1. **override关键字** 明确表示覆盖父类虚函数,增强代码可读性: ```cpp class Derived : public Base { public: void func() override { ... } }; ``` 2. **虚析构函数** 必须为多态基类声明虚析构函数,防止内存泄漏: ```cpp class Base { public: virtual ~Base() = default; }; ``` 3. **final关键字** 禁止类被继承或方法被重写: ```cpp class FinalClass final { ... }; class Base { public: virtual void func() final { ... } }; ``` #### 五、典型应用场景 1. GUI框架:不同控件统一事件处理接口 2. 插件系统:通过基类接口扩展功能 3. 算法策略:运行时选择不同算法实现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值