Interface的Object之间的关系问题

本文探讨了Java中接口与Object类的关系问题,通过对比Java和C#的编译方式,解释了为何Java接口可以调用Object类的方法,以及编译器如何处理此类情况。
 Interface的Object之间的关系问题
一直没有读过什么经典的Java书籍,有时候被学员拿着《think in java》中一些看不懂的地方来问我,我才顺便跟着看上一页两页的。我现有的java知识都是零零散散收集的和在大量的教学实践中自我总结的,所以,我掌 握的java知识体系不够系统。我现在有一个非常基础的问题,不知道有没有朋友能够给出权威的解释,最好能给出解释的原文出处,鄙人将不胜感激!
一 个接口没有继承Object类,但我们在任何接口上调用Object类的方法,编译器都不报错,这种现象该如何解释呢?例如,下面的代码中 Runnable是一个接口,但我们针对这个接口调用了Object类的一些方法,可以成功通过编译,是不是编译器对这种情况进行了特殊对待?
class InterfaceAndObject
{
 public void interfaceTest(Runnable r)
 {
  System.out.println(r.toString() + r.hashCode());
 }
}

这是张孝详blog上的内容
http://blog.youkuaiyun.com/zhangxiaoxiang/archive/2006/09/03/1173253.aspx?Pending=true

我样应该是这样的。
   一般,如果一个类未继承任何类,那么编译器将使用两种方法处理。
1:为这个类指定一个默认的类来继承,c#就是这样。
2:由解析器来处理,即如果发现某个类未从任何类继承,就将这个类强行解释为从一个默认类继承,但

并不将继承的代码写的二进制执行文件中。

下面就来证明我的观点。其实要证明这一点非常简单。由于c#和java最终都生成中间语言,并且不管源码

是什么样,生成的中间语言都会保持原始状态,即如果是在编译时将这个默认父类加上,虽然在源码中未

继承这个父类,但在中间语言中必然会有所体现。

这是一个java类
class MyClass implements Runnable
{
    public void run()
    {
       
    }
}

使用DJ java Decompiler进行反编译,反编译成字节码
class MyClass
    implements Runnable
{

    MyClass()
    {
    //    0    0:aload_0        
    //    1    1:invokespecial   #10  <Method void Object()>
    //    2    4:return         
    }

    public void run()
    {
    //    0    0:return         
    }
}
可以看出,并未有extends Object出现。

而看下面一段c#代码(由于C#没有Runnable接口,因此,定义一个)

    interface Runnable
    {
        void run();
    }
    class MyClass : Runnable
    {
        public void run()
        {
        }
    }

使用c#自带的ildasm.exe反编译成中间语言
.class private auto ansi beforefieldinit WindowsApplication1.MyClass
       extends [mscorlib]System.Object
       implements WindowsApplication1.Runnable
{
} // end of class WindowsApplication1.MyClass

可以看到多出个extends [mscorlib]System.Object来,因此,c#是编译在编译时自动加上的

System.Object,而java是由解析器来自动解析的(java的编译器源码是什么就编译成什么样子,而不像

c#的编译器,加一些额外的东西。

最后看一下Runnable.class的反编译结果
public interface Runnable
{

    public abstract void run();
}

可就是一个单独定义的接口,它可没从Object继承。
### 面向对象编程中对象之间关系 面向对象编程(Object-Oriented Programming, OOP)是一种以对象为核心的编程范式,其中对象是类的实例。在面向对象编程中,对象之间关系可以通过多种方式来定义和描述,主要包括关联、继承、组合等核心概念[^1]。 #### 1. 关联(Association) 关联表示两个或多个对象之间存在一种使用或交互的关系。这种关系可以是单向的、双向的或多向的。例如,在一个订单系统中,客户对象与订单对象之间可能存在关联关系,客户可以创建订单,而订单属于某个客户[^2]。 #### 2. 继承(Inheritance) 继承是一种“is-a”的关系,表示一个类可以从另一个类派生出来。子类会继承父类的属性和方法,并且可以扩展或重写这些方法以适应特定的需求。例如,`Animal` 类是一个通用类,而 `Dog` 和 `Cat` 是从 `Animal` 派生出来的子类,它们继承了 `Animal` 的公共特性[^3]。 ```python class Animal: def __init__(self, name): self.name = name def speak(self): pass class Dog(Animal): def speak(self): return "Woof!" class Cat(Animal): def speak(self): return "Meow!" ``` #### 3. 组合(Composition) 组合是一种“has-a”的关系,表示一个对象包含另一个对象作为其组成部分。组合通常用于构建更复杂的对象结构。例如,一辆汽车对象可能包含发动机对象、轮胎对象等多个部分。如果汽车被销毁,这些部分也会随之销毁[^4]。 ```python class Engine: def start(self): return "Engine started" class Car: def __init__(self): self.engine = Engine() def start(self): return self.engine.start() ``` #### 4. 聚合(Aggregation) 聚合也是一种“has-a”的关系,但它与组合的区别在于聚合中的对象具有独立的生命期。例如,大学和学生之间关系可以是聚合关系,学生可以存在于大学之外[^5]。 #### 5. 实现(Realization) 实现通常出现在接口和具体类之间,表示一个类实现了某个接口所定义的行为。例如,在 JavaC# 中,一个类可以通过实现接口来提供特定功能[^6]。 ```java public interface Flyable { void fly(); } public class Bird implements Flyable { public void fly() { System.out.println("Bird is flying"); } } ``` ### 总结 面向对象编程中的对象关系通过关联、继承、组合、聚合和实现等方式来表达。每种关系都有其独特的语义和应用场景,开发者需要根据实际需求选择合适的关系模型[^7]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值