理解extends与implements

本文详细解析了Java中extends关键字用于实现类的继承,以及implements关键字用于实现接口的方法。介绍了Java与C++在继承方面的差异,并通过具体示例说明如何在Java中正确使用这些概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近写android的应用程序,都是java编程的思想,和C++还是有所不同的,主要是继承上有所不同,其中对extends与implements的理解如下:

1、extends是子类继承父类的关键字,继承父类之后,可以使用父类的方法,也可以复写父类的方法。

implements是一个类实现一个或者多个接口。接口的方法一般是空的,按我做C++之前的理解就是纯虚函数,需要重新写方法才能使用。

如果implements一个接口就必须实现这个接口的所有方法。

2、java和C++不同,不支持多重继承,但是可以用接口实现,也就是说extends只能继承一个类,而implements可以实现一个或多个接口。

例如:class Child extends Parents implements method InterfaceA,InterfaceB.InterfaceC

还要注意接口和接口直接可以extends继承。

例如:

public interface UInterface {

     void onDeviceRun(int id);
}

interface PInterface  extends UInterface {

     void onOtherRun();

}

class Example implements PInterface{

     void onDeviceRun(int id){

     System.out.println(id+" PInterface");

}

    void onOtherRun(){

   System.out.println("onOtherRun");

}

转载于:https://www.cnblogs.com/candycaicai/archive/2011/04/20/2022210.html

<think>我们正在构建一个AIDL服务端,需要创建一个继承自Binder并实现特定接口的抽象类(Stub类)。根据AIDL的机制,这个Stub类将由AIDL编译器自动生成,但我们需要理解其结构以便在服务端使用。 根据引用[2]和引用[4],我们可以总结出以下关键点: 1. Stub类是一个抽象类,继承自Binder并实现AIDL接口。 2. Stub类中有一个`asInterface`方法,用于将IBinder对象转换为接口类型。如果客户端和服务端在同一进程,则直接返回Stub本身(因为Stub实现了接口);如果在不同进程,则返回一个代理类(Proxy)。 3. 服务端需要实现Stub类中定义的接口方法(即AIDL中声明的方法)。 因此,服务端的实现步骤为: 1. 定义AIDL接口文件(例如`IMyService.aidl`)。 2. 编译项目,生成对应的Java接口文件(例如`IMyService.java`),其中包含Stub类。 3. 在服务端,创建一个类(例如`MyServiceImpl`)继承自Stub类,并实现接口方法。 4. 在Service的`onBind`方法中返回这个实现类的实例。 下面我们具体说明: 第一步:定义AIDL接口 例如,我们定义一个简单的AIDL接口`IMyService.aidl`: ```aidl // IMyService.aidl package com.example; interface IMyService { String getMessage(); } ``` 第二步:编译后,系统会生成`IMyService.java`文件,其中包含: ```java public interface IMyService extends android.os.IInterface { /** 默认的DESCRIPTOR字符串,通常是接口的全限定名 */ public static final java.lang.String DESCRIPTOR = "com.example.IMyService"; /** 方法标识 */ public java.lang.String getMessage() throws android.os.RemoteException; /** 抽象Stub类 */ public static abstract class Stub extends android.os.Binder implements com.example.IMyService { // ... 其他代码 // 构造方法 public Stub() { this.attachInterface(this, DESCRIPTOR); } // asInterface方法:将IBinder转换为接口 public static com.example.IMyService asInterface(android.os.IBinder obj) { if ((obj == null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin != null) && (iin instanceof com.example.IMyService))) { return ((com.example.IMyService) iin); } return new com.example.IMyService.Stub.Proxy(obj); } // onTransact方法:处理跨进程调用 @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException { // ... 根据code调用相应的方法 } // 代理类Proxy,用于跨进程时在客户端代理调用 private static class Proxy implements com.example.IMyService { private android.os.IBinder mRemote; Proxy(android.os.IBinder remote) { mRemote = remote; } @Override public android.os.IBinder asBinder() { return mRemote; } @Override public java.lang.String getMessage() throws android.os.RemoteException { // ... 通过mRemote.transact()发起跨进程调用 } } } } ``` 第三步:在服务端实现具体的服务类,继承自Stub类,并实现接口方法。 ```java public class MyServiceImpl extends IMyService.Stub { @Override public String getMessage() throws RemoteException { return "Hello from server"; } } ``` 第四步:在Service的`onBind`方法中返回这个实现类的实例。 ```java public class MyService extends Service { private final MyServiceImpl binder = new MyServiceImpl(); @Override public IBinder onBind(Intent intent) { return binder; // 因为MyServiceImpl继承自Binder(Stub继承Binder),所以可以直接返回 } } ``` 客户端绑定服务后,通过`IMyService.Stub.asInterface(service)`获取接口实例,然后调用方法。 总结: 1. Stub类是一个抽象类,继承Binder并实现AIDL接口,它负责将Binder对象转换为接口对象(通过`asInterface`方法)。 2. 服务端需要创建一个类继承Stub类,并实现接口中定义的方法。 3. 在Service的`onBind`方法中返回这个实现类的实例。 注意:Stub类是由AIDL编译器自动生成的,我们不需要手动编写,只需要在服务端实现它即可。 引用说明: - 引用[2]说明了Stub类是一个抽象类,继承Binder并实现接口,需要程序员实现具体的服务方法。 - 引用[4]展示了`asInterface`方法的实现细节,说明了如何将IBinder转换为接口对象。 相关问题: 1. 如何定义AIDL接口文件? 2. 在AIDL中如何传递自定义对象? 3. 如何实现AIDL的异步调用? 4. 如何确保AIDL服务的安全性(权限验证)? 5. AIDL服务如何通知客户端(回调机制)?</think>### Android AIDL 服务端实现:继承 Binder 并实现接口的 Stub 类 在 Android AIDL 实现中,服务端需要创建一个继承 `Binder` 并实现特定接口的抽象类(Stub 类)。以下是完整实现步骤: #### 1. 定义 AIDL 接口文件 ```aidl // IMyService.aidl package com.example.service; interface IMyService { String getMessage(); int calculate(int a, int b); } ``` #### 2. 实现服务端 Stub 类 ```java public class MyServiceImpl extends IMyService.Stub { // 实现接口方法 @Override public String getMessage() throws RemoteException { return "Hello from AIDL Service!"; } @Override public int calculate(int a, int b) throws RemoteException { return a + b; } // 添加类型转换方法 public IMyService asInterface(IBinder binder) { return IMyService.Stub.asInterface(binder); } } ``` 关键点说明: 1. **继承结构**:`Stub` 类继承 `Binder` 并实现 AIDL 接口[^2] 2. **抽象类**:`Stub` 是抽象类,需要实现所有接口方法 3. **类型转换**:通过 `asInterface()` 方法实现 `IBinder` ↔ 接口的转换[^4] #### 3. 在 Service 中绑定 Stub ```java public class MyService extends Service { private final MyServiceImpl serviceImpl = new MyServiceImpl(); @Override public IBinder onBind(Intent intent) { // 返回Stub实例(也是Binder实例) return serviceImpl; } } ``` #### 4. AndroidManifest 配置 ```xml <service android:name=".MyService" android:exported="true"> <intent-filter> <action android:name="com.example.service.MY_SERVICE"/> </intent-filter> </service> ``` #### 5. 客户端绑定服务 ```kotlin // 参考引用[3]的实现 class MainActivity : AppCompatActivity() { private var myService: IMyService? = null private val conn = object : ServiceConnection { override fun onServiceConnected(name: ComponentName?, service: IBinder?) { // 类型转换:Binder → 接口 myService = IMyService.Stub.asInterface(service) } override fun onServiceDisconnected(name: ComponentName?) { myService = null } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val intent = Intent("com.example.service.MY_SERVICE").apply { `package` = "com.example.serviceapp" // 服务端包名 } bindService(intent, conn, Context.BIND_AUTO_CREATE) } fun callService(view: View) { myService?.run { val result = calculate(5, 3) Toast.makeText(this@MainActivity, "Result: $result", Toast.LENGTH_SHORT).show() } } } ``` #### 关键机制解析 1. **Stub 类结构**: - 继承 `Binder` 获得跨进程通信能力 - 实现 AIDL 接口定义服务契约 - 自动处理序列化/反序列化 2. **类型转换原理**: ```java // Binder → 接口转换 public static IMyService asInterface(IBinder binder) { if (binder == null) return null; // 同进程直接转换 if (binder instanceof IMyService) { return (IMyService) binder; } // 跨进程返回代理对象 return new Proxy(binder); } ``` 3. **跨进程通信流程**: ```mermaid sequenceDiagram 客户端->>+Stub: 调用接口方法 Stub->>+Binder驱动: 打包方法参数 Binder驱动->>+服务端Stub: 传递调用请求 服务端Stub->>+服务实现: 执行实际逻辑 服务实现-->>-服务端Stub: 返回结果 服务端Stub-->>-Binder驱动: 打包结果 Binder驱动-->>-客户端: 返回结果 ``` #### 最佳实践建议 1. **线程安全**: - Binder 调用默认在 Binder 线程池执行 - 使用 `Handler` 将结果转发到 UI 线程 2. **异常处理**: ```java @Override public int calculate(int a, int b) throws RemoteException { try { return a + b; } catch (Exception e) { throw new RemoteException("Calculation error"); } } ``` 3. **性能优化**: - 避免在单个调用中传输大数据(>1MB) - 使用 `ParcelFileDescriptor` 传输大文件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值