Java中的“虚函数”,抽象类的抽象函数

来源:互联网 发布:物流网络包括 编辑:程序博客网 时间:2024/05/21 10:28

在C++中通常可以通过虚函数实现多态, 在Java中可以通过抽象类的抽象方法实现;

所以在这里可以将 abstract 理解为 virtual但是又不完全这样理解;

在Java中,abstract 还要在类的声明前面添加,函数前面也要添加;


在Java中,接口可以理解为C++重的纯虚函数; 同时在Java中,接口还承担了类的多继承的任务,因为Java中类的直接继承只可以但继承;

为了更好的理解接口,可以参考Java中的二维绘图类的实现;


当然也可以将java 接口类看做纯虚类;



示例:

abstract class animal
{
public animal()
{
}

public abstract void show();


}


class fish extends animal
{

public void show()
{
System.out.println("fish dothis");
}

};




class bird extends animal
{
public void show()
{
System.out.println("bird dothis");
}

};
/**/
public class hello
{


    public static void main( String[] args)
   {
     System.out.println("hello world!");
  
  
  
  fish fobj = new fish();
  
  bird bobj = new bird();
  
  fobj.show();
  bobj.show();/**/
  
  animal a1 = (animal)(fobj);
  animal a2 = (animal)(bobj);
  
  a1.show();
  a2.show();
  
   }

}



运行结果:

hello world!
fish dothis
bird dothis
fish dothis
bird dothis




上面的两个示例简单的说明了Java中类型虚函数的应用;

与我们有时候可以将java的Interface接口类当做C++中的头文件用;










上述的例子简单的说明了Java中关于类似C++多态的应用; 

但是说了这么多还没有说到重点,下面我说一下C++与Java的多台实现上的区别:


1:

C++中,为的实现继承上的多态,通常是用虚函数(关键字: virtual)来实现的,实际上这样通过虚函数表实现了多态,关于虚函数表的可以自己查找相关文章;


2:

Java中,所有的函数继承,我们可以理解为,java类中的函数都是虚函数,在继承的时候默认的就像C++中的函数声明了关键字virtual一样;


下面通过两个示例说明:



示例一: java示例


class CTest{    public CTest( MainActivity mactivity )    {        m_activity = mactivity;        m_btn = (TextView) (m_activity.findViewById(R.id.textView));        final Handler m_handlerThread = new Handler();        new Thread()        {            @Override            public void run()            {                //super.run();                while (true)                {                    try                    {                        sleep(2000);                    } catch (InterruptedException e)                    {                        e.printStackTrace();                    }                    m_handlerThread.post(new Runnable()                    //new Handler().post(new Runnable()                    {                        @Override                        public void run()                        {                           show();                        }                    });                }            }        }.start();    }    MainActivity m_activity;    TextView m_btn;    int m_nCount = 0;    void show()    {        m_btn.setText("CTest show: " + m_nCount++ );    }}class CText_One extends CTest{    public CText_One(MainActivity mactivity)    {        super(mactivity);    }    @Override    void show()    {        //super.show();        m_btn.setText("CText_One show");    }}

上述两个类示例化:

new CTest(this); //显示 CTest show: 
new CText_One( this ); //显示 CText_One show       //可以通过super.show()显示基类的函数;








示例2: C++示例


class CTest
{
public:
CTest()
{
AfxBeginThread( thread_UI, this );
}
~CTest()
{


}


public:


virtual void show()  //这里有virtual关键字
{
theApp.m_pMainWnd->SetWindowText( L"CTest show " );
}


static UINT thread_UI( PVOID pParam )
{
while(true)
{
Sleep(2000);


CTest * pThis = (CTest*)pParam;


pThis->show();
}

return 0;


}


};






class CText_One : public CTest
{
public:


void show()
{
theApp.m_pMainWnd->SetWindowText( L"CText_One show " );
}
};



实例化结果,和 Java结果是一致的:

new CTest; //

 
new CText_One;



如果取消virtual关键字,实例化结果:

new CText_One; 执行结果是: CTest show  和父类new CTest的结果一样;  这是因为没有虚函数表,调用的还是父类的函数;



在java中不允许一次多继承,但是允许多次继承;


通过上述两个可以说明C++和Java在类的继承上面的区别;


我们也可以简单的将java的 继承 理解为:父类的所有代码直接复制到子类上了,就像 #define的声明那样,就是复制替换; 继承就是复制,重新函数就是替换;(当然还是通过虚函数理解比较接近);


0 0