码迷,mamicode.com
首页 > 编程语言 > 详细

对于Java中main函数为虚函数以及多态的一点理解

时间:2015-09-14 10:38:07      阅读:235      评论:0      收藏:0      [点我收藏+]

标签:

Question:

1、在Java中,由于main函数的定义为: public static void main(String[] args);那么要想在main函数中调用其余的函数的话,就必须将定义为static。另外,调用其他类编写的成员函数时,却不需要该成员函数为静态的,这是为什么? 

分析: 

静态方法是属于某一个类所有,而非静态方法是属于某类的对象所有。也就是说,要想调用非静态方法,必须先调用new来得到一个类的对象,系统为其分配内存,然后才能通过该对象访问相应的非静态成员函数。而静态方法是属于某一个类所有,静态方法在执行的时候,并不一定需要类来操作,也可以通过使用类名,调用的静态方法是在哪个内中定义的,也就是调用哪个类中的静态方法。

由于main函数是程序的入口点,main函数不可能等到哪个对象创建了,分配了内存,然后才去调用他。而静态方法可以允许在创建对象之前就调用该方法。自然的,main函数必然是静态的。

而,在main函数中,通过使用new来创建其他的类的对象,此时,系统为其分配了一块内存,然后,就可以调用该类的其他的成员函数。

总而言之,之所以存在静态方法不能访问非静态方法,主要的是内存的关系。由于静态方法要比非静态方法先获得内存,在静态方法中访问非静态方法,由于此时非静态方法未曾获得内存地址,当然或出错。如果,在一个静态方法中,通过使用new来得到一个类的地址,然后在进行访问该对象的非静态方法的话,结果如何?可以测试一下:

 

public static void showResult(fatherClass father)
    {
        father.first_function();
        father.second_function();
        father.third_function();
        
        fatherClass fatherTemp;
        
        fatherTemp = new fatherClass();
        fatherTemp.first_function();
    }

可以看到,在该静态方法中,为另一个类fatherClass调用new创建了一个对象,然后,就可以通过该对象来访问该类中的成员函数,即使他不是静态方法也不会报错。

全部的程序代码为:

package multiple;

public class Multiple 
{
    public static void showResult(fatherClass father)
    {
        father.first_function();
        father.second_function();
        father.third_function();
        
        fatherClass fatherTemp;
        
        fatherTemp = new fatherClass();
        fatherTemp.first_function();
    }
    
    public static void main(String[] args) 
    {
        // TODO code application logic here
        System.out.println("First place text : ");
        fatherClass father = new fatherClass();
        sonClass son = new sonClass();
        
        showResult(father);
        
        System.out.println("Second place text : ");
        showResult(son);
    }
}

class fatherClass
{
    public void  first_function()
    {
        System.out.println("fatherClass::first_function ");
    }
    
    public void second_function()
    {
        System.out.println("fatherClass::second_function ");
    }
    
    public void third_function()
    {
        System.out.println("fatherClass::third_function ");
    }
}

class sonClass extends fatherClass
{
    public void  first_function()
    {
        System.out.println("sonClass::first_function ");
    }
    
    public void second_function()
    {
        System.out.println("sonClass::second_function ");
    }
    
    public void third_function()
    {
        System.out.println("sonClass::third_function ");
    }
}

<多态方面>

对于C++语言中,由于其方法在默认情况下不是动态绑定的,也就是说,不是后期绑定得。要想某个方法具备后期绑定属性所带来的灵活性,需要在该方法前面添加上virtual关键字来实现。而对于Java语言则不需要,因为,在Java中,动态绑定是其默认行为,不需要添加额外的关键字来实现。

C++代码:

 

#include <iostream>
using namespace std;

class CFatherClass
{
public:
    CFatherClass()
    {
    }

    ~CFatherClass()
    {
    }

public:
    virtual void first_function()
    {
        cout<<"CFatherClass::first_function"<<endl;
    }

    virtual void second_function()
    {
        cout<<"CFatherClass::second_function"<<endl;
    }

    virtual void third_function()
    {
        cout<<"CFatherClass::third_function"<<endl;
    }
};

class CSonClass : public CFatherClass
{
public:
    CSonClass()
    {
    }

    ~CSonClass()
    {
    }

public:
    virtual void first_function()
    {
        cout<<"CSonClass::first_function"<<endl;
    }

    virtual void second_function()
    {
        cout<<"CSonClass::second_function"<<endl;
    }

    virtual void third_function()
    {
        cout<<"CSonClass::third_function"<<endl;
    }
};

void showResult(CFatherClass *father)
{
    father->first_function();
    father->second_function();
    father->third_function();
}

int main(void)
{
    CFatherClass father;
    CSonClass son;

    showResult(&father);
    showResult(&son);

    return 0;
}

 

关于两者对于多态的实现原理先做一个总结:

<C++>

在C++中,如果在类中的某个函数前添加上virtual关键字,表明该函数为虚函数,编译器会对每个包含虚函数的类创建一个表(虚函数表)。在虚函数表中,编译器放置特定类的虚函数地址。在每个带有虚函数的类中,编译器秘密的放置一个指针,指向这个对象的虚函数表。当通过基类指针做虚函数调用时,编译器静态的插入能够取得这个指针并在虚函数表中查找函数地址的代码,这样就能调用正确的函数并引起晚绑定的发生。

<Java>

在Java中,为了执行后期绑定,Java使用了一小段特殊的代码来替代绝对地址调用。这段代码使用在对象中存储的信息来计算方法体的代码。通常,先搜寻子类,看起是否有存在该调用方法,如果有则调用,如果没有则向上查找,看其父类是否存在该方法,有则调用。

 

 

对于Java中main函数为虚函数以及多态的一点理解

标签:

原文地址:http://www.cnblogs.com/2013jiutian/p/4806444.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!