封装、继承、多态是面向对象编程中三个比较重要的概念,理解这3个概念对领会JAVA语言至关重要,而搞懂方法的覆盖又是理解继承的关键部分,这里主要看一下静态方法的覆盖。
首先看一段代码:
java 代码
- class Super{
- static String greeting(){
- return "Good night";
- }
-
- String name(){
- return "Richard";
- }
- }
-
- class Sub extends Super{
- static String greeting(){
- return "Hello";
- }
-
- String name(){
- return "Dick";
- }
- }
-
- class Test{
- public static void main(String[] args){
- Super s = new Sub();
- System.out.println(s.greeting()+","+s.name());
- }
- }
运行Test 类的结果为:Good night,Dick
也许你会感到迷惑,这里调用的到底是Super类的方法还是Sub子类的方法?让我们首先判断调用的是哪个类的name()方法。两个类中的name()方法都不是静态方法而是实例方法,因为Sub 类继承了Super 类而且有一个和它父类同样标识的name()方法,所以Sub 类中的name()方法覆盖了Super 类中的name()方法,那么前面提到的变量s 又是Sub 类的一个实例,这样一来s.name()的返回值就是Dick 了。
至此我们解决了问题的一半,现在我们需要判断被调用的greeting()方法究竟是Super类的还是Sub 类的。需要注意的是,两个类中的greeting()方法都是静态方法,也称为类方法。尽管事实上Sub 类的greeting()方法具有相同的返回类型、相同的方法名以及相同的方法参数,然而它并不覆盖Super 类的greeting()方法。由于变量s 被强制转换为Super 型并且Sub 类的greeting()方法没有覆盖Super 类的greeting()方法,因此s.greeting()的返回值为Goodnight 。还是很迷惑?请记住这条规则:“实例方法被覆盖,静态方法被隐藏” 。假如你就是刚才大喊不能覆盖静态方法的读者之一,那么你完全正确。现在你可能会问:“隐藏和覆盖有什么区别”?你也许还未理解这点,然而实际上我们刚刚在这个Super/Sub 类的例子中已经解释了两者的不同。使用类的全局名可以访问被隐藏的方法,即使变量s 是Sub 类的一个实例,而且Sub 类的greeting()方法隐藏了Super 类的同名方法,我们仍旧能够将s 强制转换为Super 型以便访问被隐藏的greeting()方法。与被隐藏的方法不同,对被覆盖的方法而言,除了覆盖它们的类之外其他任何类都无法访问它们,这就是为何变量s 调用的是Sub 类的而非Super 类的name()方法。
本单元简要解释了Java 语言中一个不时引起混淆的问题,也许对你来说理解隐藏静态方法和覆盖实例方法的区别的最佳方式就是自己创建几个类似于Sub/Super 的类再重复一次规则“实例方法被覆盖而静态方法被隐藏”,被覆盖的方法只有覆盖它们的类才能访问它们,而访问被隐藏的方法的途径是提供该方法的全局名。
现在你终于明白标题里问题的答案了吧?什么时候“被覆盖的”方法并非真地被覆盖了呢?答案就是“永远不会”。另外,还有几点要注意:
1. 试图用子类的静态方法隐藏父类中同样标识的实例方法是不合法的,编译器将会报
错;
2. 试图用子类的实例方法覆盖父类中同样标识的静态方法也是不合法的,编译器同样
会报错;
3. 静态方法和最终方法(带关键字final 的方法)不能被覆盖;
4. 实例方法能够被覆盖;
5. 抽象方法必须在具体类中被覆盖
分享到:
相关推荐
2. **多态性**:实例方法支持多态性,即子类可以覆盖或扩展父类的方法实现,从而实现不同的行为。 3. **灵活性**:实例方法提供了更灵活的方式来处理数据,因为它们可以利用实例的状态信息。 #### 实现方式 ```...
### Java之中的静态变量与静态方法的继承与覆盖问题 #### 静态变量与静态方法的基本概念 在Java编程语言中,静态变量(也称为类变量)和静态方法(也称为类方法)是由`static`关键字修饰的成员变量和成员方法。...
EXT dojochina Ext类静态方法是一个关于EXT框架在JavaScript中的使用的主题,主要聚焦于Ext类的静态方法。EXT是一个强大的前端开发框架,由Sencha公司开发,它提供了丰富的组件库,用于构建复杂的Web应用程序。在EXT...
然而,有些情况下,正常的单元测试框架可能无法覆盖到所有的情况,比如静态方法和私有方法的测试。这时,我们就需要引入特殊的工具,如PowerMock。本文将详细介绍如何利用PowerMock来模拟静态方法和私有方法,以便...
在静态方法中,由于它可以重写任何静态数据成员的值,因此静态方法可以覆盖静态变量的值。非静态方法也可以覆盖静态变量的值,但需要创建类对象。 七、内存分配 静态方法的内存是固定在内存中的,因此,我们不需要...
同时,静态方法和实例方法不能互相覆盖,因为它们在字节码中的绑定方式不同:实例方法是在运行时动态绑定,而静态方法是在编译时静态绑定。理解这些概念对于编写高效且易于维护的Java代码至关重要。
4. **静态方法不可被覆盖**: 在Java中,静态方法是不能被覆盖的,因为静态方法与类绑定而不是与对象绑定。 5. **最终方法不可被覆盖**: 如果父类中的方法被声明为`final`,那么这个方法不能被子类覆盖。 6. **...
虽然这不是真正意义上的重写,因为静态方法在Java中不能被覆盖,但子类可以拥有与父类静态方法相同签名的静态方法。这样做可能会导致命名冲突,因此在设计时需要特别注意。如果在子类中调用同名的静态方法,Java...
4. **多态性无关**:静态方法不参与多态性,它们总是根据定义它们的类来调用,不会因为子类覆盖而改变行为。 然而,静态方法也有一些限制: 1. **无法访问实例变量**:静态方法不能访问或修改类的实例变量,因为...
总的来说,使用PowerMock来Mock静态函数是提高测试覆盖率和确保代码质量的重要手段。通过模拟静态方法,我们可以更好地测试那些依赖静态方法的复杂逻辑,确保我们的代码在各种情况下都能按预期工作。在实际开发中,...
静态方法和属性在子类中会被继承,并且可以被覆盖。子类可以有自己的静态方法和属性,同时也可以访问父类的静态方法和属性。 7. **性能考虑**: 静态方法和属性的使用可以减少内存消耗,因为不需要创建对象实例。...
静态方法不能被覆盖,因为它们是密封的(sealed),而抽象方法是设计为被子类覆盖的。因此,将静态方法放在抽象类中,可以确保这个方法不会被子类重写,保持其行为一致性。 以下是一个简单的示例,展示了如何在C#中...
如果一个父接口提供一个默认方法,而另一个接口也提供了一个具有相同名称和参数列表的方法(不管方法是否是默认方法),那么必须覆盖该方法来解决冲突。 静态方法 在Java8中,接口中也可以声明静态方法。静态方法...
标题和描述提到的"婚庆静态前景66个高清透明覆盖图像"是一套专为婚礼设计的素材集合,包含66个高质量图像,适用于制作邀请函、视频剪辑、网页设计、社交媒体封面等多个方面。 首先,我们要理解什么是静态前景。静态...
本压缩包文件“网络游戏-无线传感器网络静态节点最优覆盖控制集求解方法.zip”包含的核心内容是关于如何在WSN中实现静态节点的最优覆盖控制集的求解策略。 首先,我们要理解“覆盖控制集”的概念。在WSN中,覆盖是...
从输出结果可以看到,子类的静态方法不能覆盖父类的静态方法。即使子类中有一个和父类一模一样的静态方法,也只是子类本身的静态方法,而不是父类的静态方法的重写。 这是因为静态方法属于类,而不是对象。静态方法...
在Python编程中,类的方法分为三种类型:实例方法、类方法和静态方法,它们各自有特定的使用场景和特点。 1. 实例方法 实例方法是通过实例对象调用的方法,通常第一个参数是`self`,它指向调用该方法的实例对象。...
另外静态方法不能覆盖父类的实例方法,而静态变量却可以隐藏父类的一个同名实例变量,同样,实例方法不能覆盖父类的同名静态方法,而变量却可以隐藏父类的同名变量成员,不论父类的这个变量成员是类变量或者是实例...
但是,滥用静态方法可能会影响代码的可测试性和可维护性,因为静态方法无法被覆盖和重写,这限制了面向对象的多态性原则的使用。另一方面,实例方法则天然支持面向对象设计原则,比如封装、继承和多态。 总而言之,...