动态绑定和静态绑定

动态绑定

动态绑定是指编译器在编译阶段不知道要调用哪个方法

Parent父类,父类有两个方法一个是类方法shout,一个是实例方法say

public class Parent {
    String name;
    public static void shout(){
        System.out.println("我是父类shout静态方法");
    }

    public void say(){
        System.out.println("我是父类say方法");
    }
}

Son子类继承父类,并重写了say实例方法

public class Son extends Parent {
    String name;
    @Override
    public void say() {
        System.out.println("我是子类say");
    }
}

测试函数

public class MainTest {
    public static void main(String[] args) {
        Parent parent = new Parent();
        Parent son = new Son();
        parent.say();
        son.say();
    }
}

声明的两个对象都是parent类型,但运行时他们指向的都是不同的对象类型

虽然调用的是say方法但是编译器在编译阶段不能确定调用的是子类还是父类的方法,方法的动态绑定是基于实际的对象类型,而不是它们声明的对象引用类型

静态绑定

我们知道静态方法不能被重写,为什么呢,其实这就和静态绑定有关.编译器在编译期间就能完成绑定的叫做静态绑定也叫前期绑定,基本上实例方法都在运行时绑定,静态方法是静态绑定在编译期间就已经决定的

给父类和子类同时加上静态方法

public static void shout(){
        System.out.println("我是父类shout静态方法");
}
public static void shout(){
        System.out.println("我是子类shout静态方法");
}

测试

public static void main(String[] args) {
        Parent parent = new Parent();
        Parent son = new Son();
        parent.shout();
        son.shout();
    }

运行结果

我是父类shout静态方法
我是父类shout静态方法

虽然java允许重写静态方法但是无效,调用的静态方法是父类的静态方法

成员变量的静态绑定

父类添加属性

String name="parent";

子类添加属性

String name="son";

测试

public static void main(String[] args) {
        Parent parent = new Parent();
        Parent son = new Son();
        System.out.println(son.name);
        System.out.println(parent.name);
    }

运行结果

parent
parent

总结一下静态绑定存在于以下几种情况
1. 类方法
2. 私有方法(不会被继承)
3. 访问成员变量

### C++ 动态绑定静态绑定 #### 概念定义 在C++编程中,绑定(Binding)的是将变量函数名转换为内存地址的过程。这一过程依据发生的时间不同被区分为两种形式:静态绑定动态绑定。 - **静态绑定**是编译器编译期间就决定了要调用的具体函数版本[^1]。这意味着当代码被编译时,所有的函数调用都已经被解析并链接到特定的目标位置。 - **动态绑定**则是直到程序运行时才会确定实际调用哪一个函数版本[^2]。这种机制允许子类重写父类的方法,并且可以在不改变原有接口的情况下引入新的行为逻辑。 #### 主要区别 两者之间最显著的区别在于它们发生的时刻以及由此带来的特性差异: | 特征 | 静态绑定 | 动态绑定 | | -- | --- | | 发生时间 | 编译期 | 运行期 | | 类型依赖 | 对象的静态类型 | 对象的实际(动态)类型 | | 函数选择 | 基于声明类型的成员方法 | 跟随对象的真实类型,仅限虚函数 | 对于非虚函数而言,无论何时都会按照静态绑定的方式处理——即总是会调用与声明类型相匹配的那个版本;而对于标记了`virtual`关键字的成员函数,则遵循动态绑定原则,在运行过程中根据当前实例所属的确切类别来定位最终应被执行的方法体[^4]。 #### 使用场景 ##### 静态绑定适用场合 由于静态绑定是在编译阶段完成的,因此它具有较高的性能优势,适合用于那些不需要考虑多态特性的简单情况。例如,如果应用程序设计中不存在基类派生关系或者并不涉及任何可能的变化需求,那么完全可以利用静态绑定提高执行效率[^3]。 ```cpp class Base { public: void show() { cout << "Base class"; } }; int main(){ Base b; b.show(); // 此处show()属于静态绑定 } ``` ##### 动态绑定适用场合 另一方面,当存在复杂的继承结构并且希望能够在不影响现有功能的前提下轻松添加新特征时,就应该优先选用支持动态绑定的设计模式。特别是面对开放封闭原则的要求下,借助虚拟表(VTBL)技术实现的动态分发能够很好地满足此类需求[^5]。 ```cpp #include <iostream> using namespace std; class Animal{ protected: string name; public: virtual void speak()=0; //纯虚函数 }; class Dog : public Animal{ public: Dog(){name="Dog";} void speak(){cout<<name<<" says Woof!";} }; void makeSpeak(Animal &a){ a.speak(); } int main(){ Dog d; makeSpeak(d); //此处speak()属于动态绑定 } ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值