这是最常用的三种语言,而三种语言都是面向对象的,而多态算是面向对象的灵魂,所以列出三种语言多态下的使用方式,比较记忆:
C++
1 Class Item_base{ 2 3 public: 4 5 Item_base(const string &book="", double sales_price=0.0) : isbn(book), price(sales_price){} 6 7 string book() const { return isbn;} 8 9 virtual double net_price(std::size_t n) const { return n*price;} // virtual保留字只能在类内部的成员函数声明中出现,不能用在类定义体外部出现的函数定义上 10 11 virtual ~Item_base() {} 12 13 private: 14 15 string isbn; 16 17 protected: 18 19 double price; 20 21 }; 22 23 Class Bulk_item : public Item_base { //只有C++中有公有继承 24 25 public: 26 27 double net_price(std::size_t) const; // 可加virtual或不加,反正都是虚函数,由基类决定 28 29 private: 30 31 std::size_t min_qty; 32 33 double discount; 34 35 };
void main()
{
Bulk_item bulk;
Item_base *pBase=&bulk; // 隐式类型转换
pBase->net_price(1);
Item_base *pBase2 = new Bulk_item();
pBase2->net_price(2);
delete pBase2;
}
//必须通过基类类型的引用或指针进行函数调用才能实现多态
C++中一旦函数在基类中声明为虚函数,它就一直为虚函数,派生类无法改变该函数为虚函数这一事实。派生类重定义虚函数时,可以使用virtual保留字,但不是必须这样做、
C#
1 public class Animal 2 { 3 public virtual void Eat() 4 { 5 Console.WriteLine("Eat something"); 6 } 7 } 8 9 public class Cat : Animal 10 { 11 public override void Eat() 12 { //完全取代基类方法 13 Console.WriteLine("Eat small fishes!"); 14 } 15 } 16 public class Dog : Animal 17 { 18 public override void Eat() 19 { //完全取代基类方法 20 Console.WriteLine("Eat small bones!"); 21 } 22 } 23 24 static void Main(string[] args) 25 { 26 Animal mycat = new Cat(); 27 Animal mydog = new Dog(); 28 mycat.Eat(); 29 mydog.Eat(); 30 }
// 阻止成员被继承
1 sealed class A 2 { 3 int test; 4 public void Sum(int i,int j) 5 { 6 int sum = i + j; 7 Console.WriteLine("I am A ,my sum ={0}",sum); 8 } 9 } 10 class B : A 11 { 12 public void Minus(int i,int j) 13 { 14 int minus = i - j; 15 Console.WriteLine("I am B ,my minus ={0}", minus); 16 this.Sum(3, 4); //编译器会报错 17 } 18 }
C#只有public继承。
Java:
1 public class Wine { 2 public void fun1(){ 3 System.out.println("Wine 的Fun....."); 4 fun2(); 5 } 6 7 public void fun2(){ 8 System.out.println("Wine 的Fun2..."); 9 } 10 } 11 12 public class JNC extends Wine{ 13 /** 14 * @desc 子类重载父类方法 15 * 父类中不存在该方法,向上转型后,父类是不能引用该方法的 16 * @param a 17 * @return void 18 */ 19 public void fun1(String a){ 20 System.out.println("JNC 的 Fun1..."); 21 fun2(); 22 } 23 24 /** 25 * 子类重写父类方法 26 * 指向子类的父类引用调用fun2时,必定是调用该方法 27 */ 28 public void fun2(){ 29 System.out.println("JNC 的Fun2..."); 30 } 31 } 32 33 public class Test { 34 public static void main(String[] args) { 35 Wine a = new JNC(); 36 a.fun1(); 37 } 38 } 39 ------------------------------------------------- 40 Output: 41 Wine 的Fun..... 42 JNC 的Fun2...
Java中,不需要将方法声明为虚拟方法。动态绑定是默认的处理方式。如果不希望让一个方法具有虚拟特征,可以将它标记为final。
ps:
C++中的公有继承,私有继承,保护继承区别:
一个子类继承父类时,可按照public、private和protected方式继承父类,每种继承方式的区别如下:
1) public继承方式
- 基类中所有public成员在派生类中为public属性;
- 基类中所有protected成员在派生类中为protected属性;
- 基类中所有private成员在派生类中不可访问。
2) protected继承方式
- 基类中的所有public成员在派生类中为protected属性;
- 基类中的所有protected成员在派生类中为protected属性;
- 基类中的所有private成员在派生类中仍然不可访问。
3) private继承方式
- 基类中的所有public成员在派生类中均为private属性;
- 基类中的所有protected成员在派生类中均为private属性;
- 基类中的所有private成员在派生类中均不可访问。