1,被忽略的细节:
1,冒号( :)表示继承关系,Parent 表示被继承的类,public 的意义是什么?
class Parent
{ }; class Child : public Parent
{ };
2,有趣的问题:
1,是否可以将继承语句中的 public 换成 protected 或者 private?如果可以,与 public 继承有什么区别?
3,有趣的尝试编程实验:
#include <iostream>
#include <string> using namespace std; class Parent
{
}; class Child_A : public Parent
{
}; class Child_B : protected Parent
{
}; class Child_C : private Parent
{
}; int main()
{
return ;
}
1,protected 和 private 地位对等,推理的角度可以过,实际的编译结果也是同样的结论;
2,本文主要分析这三种继承方式有何不同;
4,不同的继承方式(这是父类成员在子类中被外界访问的级别):
1,C++ 中支持三种不同的继承方式;
1,public 继承:
1,父类成员在子类中保持原有访问级别;
2,private 继承:
1,父类成员在子类中变为私有成员;
3,protected 继承:
1,父类中的公有成员变为保护成员,其它成员保持不变;
2,继承成员的属性:
1,Max{继承方式,父类成员访问属性};
2,C++ 中的默认继承方式为 private;
3,继承与访问级别深度实践编程实验:
#include <iostream>
#include <string> using namespace std; class Parent
{
protected:
int m_a;
protected:
int m_b;
public:
int m_c; void set(int a, int b, int c)
{
m_a = a;
m_b = b;
m_c = c;
}
}; class Child_A : public Parent
{
public:
void print()
{
cout << "m_a" << m_a << endl;
cout << "m_b" << m_b << endl;
cout << "m_c" << m_c << endl;
}
}; class Child_B : protected Parent
{
public:
void print()
{
cout << "m_a" << m_a << endl;
cout << "m_b" << m_b << endl;
cout << "m_c" << m_c << endl;
}
}; class Child_C : private Parent
{
public:
void print()
{
cout << "m_a" << m_a << endl;
cout << "m_b" << m_b << endl;
cout << "m_c" << m_c << endl;
}
}; int main()
{
Child_A a;
Child_B b;
Child_C c; a.m_c = ;
// b.m_c = 100; // Child_B 保护继承自 Parent, 所以所有 public 成员全部变成了 protected 成员, 因此外界无法访问;
// c.m_c = 100; // Child_C 私有继承自 Parent, 所以所有的成员全部变成了 private 成员, 因此外界无法访问; a.set(, , );
// b.set(2, 2, 2); // 保护继承;
// c.set(3, 3, 3); // 私有继承; a.print(); // 继承方式只影响继承自父类成员的访问方式,外界访问子类方式无影响;
b.print(); // 继承方式只影响继承自父类成员的访问方式,外界访问子类方式无影响;
c.print(); // 继承方式只影响继承自父类成员的访问方式,外界访问子类方式无影响; return ;
}
1,父类中的访问级别影响着子类的访问,但是继承级别不影响子类的访问、影响其它外部类访问父类中的成员;
5,遗憾的事实:
1,一般而言,大型的 C++ 工程项目中只使用 public 继承;
1,这已经足够了;
2,保护继承和私有继承根本就没什么用;
2,C++ 的派生语言只支持一种继承方式(public 继承);
1,Java、C# 等语言只有一种继承方式即 public 继承方式;
3,protected 和 private 继承带来的复杂性远大于实用性;
1,仅在学术研究领域研究;
6,C++ 派生语言初探编程实验:
1,D 语言(在 Linux 中用 gdc 编译,生成 *.out 文件):
module D_Demo; // 将下面的所有代码定义为模块,模块名字为
D_Demo; import std.stdio; // import 同 include
import std.string; // import 同 include class Obj // 这里定义了一个 Obj 类
{
protected:
string mName;
string mInfo; public:
this() // 这是 D 语言中的构造函数,D 语言中的构造函数统一的用 this 这个关键字表示,由 C++ 进化而来;
{
mName = "Object";
mInfo = "";
} string name() // 定义两个成员函数;
{
return mName;
} string info()
{
return mInfo;
}
} class Point : Obj // 定义了一个类 Point,其继承自 Obj,D 语言中的继承方式默认的是 public 继承;
{
private:
int mX;
int mY; public:
this(int x, int y)
{
mX = x;
mY = y;
mName = "Point";
mInfo = format("P(%d, %d)", mX, mY); // 和 C 语言中的语法规则一样;
} int x()
{
return mX;
} int y()
{
return mY;
}
} void main(string[] args) // 程序运行的入口;
{
writefln("D Demo"); // D Demo;打印语句之后空一行,同 printf; Point p = new Point(, ); // 动态生成 Point 对象; writefln(p.name()); // Point,公有继承;
writefln(p.info()); // P(1, 2),公有继承;
}
1,没学过 D 语言,但是要读懂 D 语言的代码是比较容易的;
2,如果因工作需要要学习 D 语言程序设计,将是轻而易举的事情;
2,C# 语言(Linux 中用 gmcs 编译,生成 *.exe 文件):
class Obj // 定义一个类 Obj;
{
protected string mName; // 访问属性 protected;
protected string mInfo; public Obj() // 无返回值,函数名同类名,即构造函数,访问属性为 public;
{
mName = "Object";
mInfo = "";
} public string name()
{
return mName;
} public string info()
{
return mInfo;
}
} class Point : Obj // 定义一个类 Point,继承自 Obj,只有一种 public 继承方式;
{ private int mX;
private int mY; public Point(int x, int y) // 构造函数;
{
mX = x;
mY = y;
mName = "Point";
mInfo = "P(" + mX + ", " + mY + ")"; // 通过 + 操作符来连接字符串和整型变量,最终得到一个字符串;C++ 中可以通过重载全局的 + 操作符就能够连接一个字符串和一个整型变量最终得到一个字符串,别的语言中的特性,不明白的话,考虑下在 C++ 中如何实现;
} public int x()
{
return mX;
} public int y()
{
return mY;
}
} class Program
{
public static void Main(string[] args) // 程序入口
{
System.Console.WriteLine("C# Demo"); // C# Demo Point p = new Point(, ); System.Console.WriteLine(p.name()); // Point
System.Console.WriteLine(p.info()); // P(1, 2) }
}
3,Java 程序:
class Obj
{
protected String mName;
protected String mInfo; public Obj()
{
mName = "Object";
mInfo = "";
} public String name()
{
return mName;
} public String info()
{
return mInfo;
}
} class Point extends Obj // extends 表示公有继承,更加直观;
{ private int mX;
private int mY; public Point(int x, int y)
{
mX = x;
mY = y;
mName = "Point";
mInfo = "P(" + mX + ", " + mY + ")";
} public int x()
{
return mX;
} public int y()
{
return mY;
}
} class Program {
public static void main(String[] args){ // 程序运行如口
System.out.println("Java Demo"); // Java Demo Point p = new Point(1, 2); System.out.println(p.name()); // Point
System.out.println(p.info()); // P(1, 2)
}
}
1,现在已经有能力读懂 D、C#、Java 语言程序了;
1,C#、Java 可以从事网络开发、游戏开发;
2,D 语言可以从事系统开发;
2,工程里面,仅仅使用 public 继承就够了;
7,小结:
1,C++ 中支持 3 种不同的继承方式;
2,继承方式直接影响父类成员在子类中的访问属性;
3,一般而言,工程中只使用 public 的继承方式;
4,C++ 的派生语言中只支持 public 继承方式;