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

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使用了一小段特殊的代码来替代绝对地址调用。这段代码使用在对象中存储的信息来计算方法体的代码。通常,先搜寻子类,看起是否有存在该调用方法,如果有则调用,如果没有则向上查找,看其父类是否存在该方法,有则调用。

时间: 2024-08-03 23:31:23

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

C++中的纯虚函数和虚函数的作用

1. 虚函数和纯虚函数可以定义在同一个类(class)中,含有纯虚函数的类被称为抽象类(abstract class),而只含有虚函数的类(class)不能被称为抽象类(abstract class). 2. 虚函数可以被直接使用,也可以被子类(sub class)重载以后以多态的形式调用,而纯虚函数必须在子类(sub class)中实现该函数才可以使用,因为纯虚函数在基类(base class)只有声明而没有定义. 3. 虚函数和纯虚函数都可以在子类(sub class)中被重载,以多态的形式

【继承与多态】C++:继承中的赋值兼容规则,子类的成员函数,虚函数(重写),多态

实现基类(父类)以及派生类(子类),验证继承与转换--赋值兼容规则: 子类对象可以赋值给父类对象(切割/切片) 父类对象不能赋值给子类对象 父类的指针/引用可以指向子类对象 子类的指针/引用不能指向父类对象(可以通过强制类型转换完成) #include<iostream> using namespace std; class People    //父类或者基类 { public:     void Display()     {         cout << "_na

Qt信号槽中槽函数为虚函数的一些感想

有时候,在写connect的时候会去犹豫一个问题----我的槽函数到底需不需要为虚函数.这个问题在我每次写connect的时候我都会反问自己,因为确实,如果你不去深究里面的moc,你发现不了太多问题. 比如有这么一个demo. #include <QApplication> #include <QObject> #include <QDebug> class Test : public QObject { Q_OBJECT public: void onEmit() {

C++中的 虚函数 纯虚函数 虚基类(virtual)

前言:需要了解三者的区别,必须要掌握多态的三个必要条件: 继承 重载 父类指针指向子类对象. 虚函数 纯虚函数 虚基类三者区别 1.虚函数是用于多态中virtual修饰父类函数,确保父类指针调用子类对象时,运行子类函数的. 2.纯虚函数是用来定义接口的,也就是基类中定义一个纯虚函数,基类不用实现,让子类来实现. 3.虚基类是用来在多继承中,比如菱形继承中,如果两个父类继承自同一个类,就只实例化一个父类 ①虚函数第一个是没有使用多态(只用继承)的一般实现方式: class A { public:

【转载】 C++多继承中重写不同基类中相同原型的虚函数

本篇随笔为转载,原文地址:C++多继承中重写不同基类中相同原型的虚函数. 在C++多继承体系当中,在派生类中可以重写不同基类中的虚函数.下面就是一个例子: class CBaseA { public: virtual void TestA(); }; class CBaseB { public: virtual void TestB(); }; class CDerived : public CBaseA, public CBaseB { public: virtual void TestA()

Java中的Random()函数-----转载

Java中的Random()函数 (2013-01-24 21:01:04) 转载▼ 标签: java random 随机函数 杂谈 分类: Java 今天在做Java练习的时候注意到了Java里面的一个随机函数——Random,刚开始只是知道这个函数具有随机取值的作用,于是上网搜索了资料一番,做了一下一些关于Random函数的总结: Java中存在着两种Random函数: 一.java.lang.Math.Random; 调用这个Math.Random()函数能够返回带正号的double值,该

派生类的构造函数和析构函数和多继承中的二义性与虚函数

析构函数主要作用是对数据成员初始化. 1派生类的构造函数 派生类的构造函数定义的一般形式为: 派生类名::派生类名(基类所需形参,本类成员所需形参):基类1(基类1 参数表),基类2(基类2 参数表),···,基类n(基类n 参数表),对象成员1(对象1 参数表),对象成员2(对象2 参数表),···,对象成员m(对象m 参数表){ //本类基本类型数据成员初始化 } 如果使用基类无参构造函数,派生类构造函数形参表中不包含供给基类构造函数的参数.此时,系统会调用基类的默认构造函数.如果使用对象数

java中String字符串的替换函数:replace与replaceAll的区别

例如有如下x的字符串 String x = "[kllkklk\\kk\\kllkk]";要将里面的“kk”替换为++,可以使用两种方法得到相同的结果 replace(CharSequence target, CharSequence replacement)       ——          x.replace("kk", "++") replaceAll(String regex, String replacement)       —— 

C++中不能声明为虚函数的有哪些函数

常见的不不能声明为虚函数的有:普通函数(非成员函数):静态成员函数:内联成员函数:构造函数:友元函数. 1.为什么C++不支持普通函数为虚函数? 普通函数(非成员函数)只能被overload,不能被override,声明为虚函数也没有什么意思,因此编译器会在编译时邦定函数. 多态的运行期行为体现在虚函数上,虚函数通过继承方式来体现出多态作用,顶层 函数不属于成员函数,是不能被继承的2.为什么C++不支持构造函数为虚函数? 这个原因很简单,主要是从语义上考虑,所以不支持.因为构造函数本来就是为了明