JAVA與C++的多型異同
將一個方法呼叫同一個方法主體(大多時候為派生類)關聯起來被稱做繫結。在程式執行前進行繫結,由編譯器和連結程式實現稱為前期繫結。
後期繫結:也稱動態繫結(在程式執行過程中動態實現繫結)如果一種語言想實現後期繫結,就必須具有某種機制,以便在執行時能判斷物件的型別,從而呼叫適當的方法。 也就是說,編譯器不知道物件的型別,但是方法呼叫機制能找到正確的方法體,並加以呼叫。後期繫結機制隨程式語言的不同而有所不同。
JAVA中除了static 方法和final方法之外,其他所有的方法都是後期繫結。(也就是說,後期繫結會自動發生)
EX:
//shape/Shape.java
package polymorehism.shape
import static net.arborj.util.Print.* //簡化print的一個工程類
public class Shape{
public void draw(){
print("Shape draw");
}
}
//:shape/ Circle.java
package polymorehism.shape
public class Circle externs Shape{
public void draw(){
print("Circle drwa");
}
}
//shape/ Square.java
package polymorehism.shape
public class Square externs Shape{
public void draw()
{
print("Square draw");
}
}
public class Main{
public static void main(String[] args){
Shape s = new Circle;
s.draw();
}
}
//輸出(子類成員): Circle draw
多型也不適用於屬性。
這裡雖然是一個Shape引用,後期繫結(多型)中呼叫了Circle.draw()方法。 注意Shape類中的draw方法不能是static ,(private或者final)的 ,static方法與類本身關聯,與物件無關,而private方法屬於finnal方法,派生類(也叫匯出類) 不能訪問,實現的重名draw()是一個全新的函式(與基類無關) ,故如果通過基類引用呼叫,只會呼叫基類方法(不能按照我們所期望的來執行。
還有基類中的屬性也不適用於多型。
--------------------JAVA中多型與工廠(factory)
生成工廠類Generator:
public class RandomShapeGenerator{
private Random rand = new rand(47);
public Shape next(){
switch(rand.next(3)){
default:
case 0 :return new Circle();
case 1 :return new Square();
case 2 :return new Triangle();
}
}
}
public class Shapes{
private static RandomShapeGenerator gen = new RandomShapeGenerator;
public static void main(Strings[] args){
Shape[] s= new Shape[9];
for(int i=0;i<9;i++)
{
s[i]=gen.next();
for(Shape shp:s)
{
shp.draw();
}
}
}
}
Shape基類為自它繼承而來的所有匯出類建立了一個公共介面。 RandomShapeGenerator是一個工廠類,它在每次隨機選擇的Shape物件產生一個引用(我們可以通過對工廠類傳遞引數從而通過switch返回我們需要的子類引用)。 因為程式只與基類介面通訊,這樣的程式可擴充套件的,
可以從通用的基類繼承出新的資料型別,從而新增一些新功能。(為基類新增新函式)而那些操縱基類介面的方法不需要任何改動就可以應用於新類。(將改變的事務與未變的食物分離開的)
-----------------------------------------C++中的多型。
先來看跟JAVA相同例子:
class Shape{
public:
void draw();
}
void Shape::draw(){
pirntf("Shape draw");
}
class Circle:public Shape{
public:
void draw();
}
Circle::draw(){
printf("Circle draw");
}
class Square:public Shape{
public:
void draw();
}
Circle::draw(){
prinf("Square draw ");
}
int main()
{
Circle sc1;
Square sc2;
Shape *s[] = {&sc1,&sc2};
for(int i=0;i<2;i++)
{
s[i]->draw();
}
}
//輸出基類成員Shape draw Shape draw
即通過基類指標呼叫的都是基類中定義的函式,派生類中的函式不會被呼叫
C++中的多型依賴於虛函數
虛擬函式必須是非靜態的成員函式。
虛擬函式的宣告只能出現在類定義中的函式原型宣告中,而不能在成員函式實現的時候。
賦值相容規則:在需要基類物件的任何地方都可以使用公有派生類的物件。
1:派生類物件可以賦值給基類物件。
2:派生類對戲那個可以初始化基類的引用。
3:派生類物件地址可以賦值給指向基類的指標。
C++執行時多型滿足三個條件:1,類之間滿足賦值相容規則。2基類中虛擬函式用virtual宣告。
3:由成員函式來呼叫或者通過指標,引用來訪問虛擬函式。
改進:
class Shape{
public:
virtual void draw();
}
void Shape::draw(){
pirntf("Shape draw");
}
class Circle:public Shape{
public:
void draw(); //覆蓋基類的虛擬函式
}
Circle::draw(){
printf("Circle");
}
class Square:public Shape{
public:
void draw(); //覆蓋基類的虛擬函式
}
Circle::draw(){
prinf("Square");
//Shape::draw(); 可以通過這種方式呼叫基類被覆蓋的函式。
}
int main()
{
Circle sc1;
Square sc2;
Shape *s[] = {&sc1,&sc2};
for(int i=0;i<2;i++)
{
s[i]->draw();
}
}
//輸出子類成員:Circle draw , Square draw .
必須要通過指標或者引用來訪問虛擬函式,如果是通過物件名來訪問虛擬函式,則繫結在編譯過程中就可以進行(靜態繫結),而無需在執行過程進行。(
相關文章
- Objective-C 與 C++ 的異同ObjectC++
- Dart 入門 & 與 ts 型別系統的異同Dart型別
- Java中Error和Exception的異同以及執行時異常(Runtime exception)與檢查型異常(checked exception)的區別JavaErrorException
- Hive與Impala的異同Hive
- java繼承與多型Java繼承多型
- HashData和Snowflake的“同”與“異”
- C++——多型C++多型
- C++多型C++多型
- Java中的類繼承與多型Java繼承多型
- Java 的多型Java多型
- bug 管理與缺陷管理的異同
- 深入理解 C++ 中的多型與檔案操作C++多型
- oracle與infomix異同點Oracle
- 淺析容器安全與EDR的異同
- JavaScript中var與let的異同點JavaScript
- SAP HANA與BWA的異同點CB
- java中的多型Java多型
- Java 中 this 和 super 的用法概述及異同Java
- C++八股之函式過載與重寫-靜態多型與動態多型C++函式多型
- Java異常型別Java型別
- DevOps與敏捷異同 - DZone DevOpsdev敏捷
- Java多型Java多型
- Tensor與tensor深入分析與異同
- C++ 多型的實現及原理C++多型
- python 元組與列表的異同點 1125Python
- c++菱形繼承、多型與類記憶體模型C++繼承多型記憶體模型
- C++整理16_多型C++多型
- 策略模式和模板方法同與異模式
- 什麼是Java多型?如何實現Java多型?Java多型
- java多型demoJava多型
- java多型特性Java多型
- [原創][連載]nim與python的異同1Python
- 【譯】Object與Map的異同及使用場景Object
- 【譯】Array與Set的異同及使用場景
- Java集合詳解7:一文搞清楚HashSet,TreeSet與LinkedHashSet的異同Java
- 何為Java 中的多型?Java多型
- Java-對多型的理解Java多型
- 開心檔之C++ 多型C++多型
- 【C/C++】c++多程式與hiredis的淺使用C++Redis