抽象类(abstract class)和接口(interface)分析
2017-11-24 22:22
363 查看
个人博客:www.letus179.com
接口: 抽象方法的集合,方法没有具体实现即不包含方法体。
接口方法能否用
不能。因为接口是对外开放的,需要具体的类来实现其中的方法,私有的方法作用范围为本类,在接口中定义私有方法没有任何意义,编译不会通过。
接口方法能否用
不能。
接口方法能否用
这和jdk版本有关。jdk8之前:不能;jdk8新特性: 能。
——参见JDK8新特性之接口的静态方法和默认方法
可以看到,
1.在成员变量(常量)中默认的修饰符是
2.在方法中,默认的修饰符是
可以看到,成员方法和成员变量和普通类一样,是什么修饰就是什么。
可以看到,和
具体的
概念
抽象类:包含抽象方法的类就称为 抽象类;接口: 抽象方法的集合,方法没有具体实现即不包含方法体。
两者异同
相同点
都不能被实例化;
接口的实现类或
抽象类的子类都必须实现
接口或
抽象类中的方法后才能被实例化
不同点
接口中的方法是高度抽象的,只有定义,没有具体的实现;
抽象类中可以有定义也可以有实现;
接口中的方法默认为
public abstract, 可以直接写
public, 可以都省略不写;
接口中方法修饰符不能是
private, 接口需要实现,所以私有的方法没有意义;
抽象类中的具体实现的方法和普通的类一样,而只有定义的方法必须用
abstract修饰,不然
编译不通过;而且
抽象方法的修饰符不能是
private,
static,
synchronized,
native,能用
默认的,
public和
protected。
接口中定义变量默认为
public static final, 并且要赋予
初始值,不然编译不通过;
抽象类和普通的类一样,可以有自己的成员变量,可以重新赋值;
接口需要
实现(implements),
抽象类需要
继承(extends),一个类可以实现多个接口,但是只能继承一个抽象类(单继承多实现)。
接口三问
接口方法能否用private
修饰
不能。因为接口是对外开放的,需要具体的类来实现其中的方法,私有的方法作用范围为本类,在接口中定义私有方法没有任何意义,编译不会通过。接口方法能否用synchronized
修饰
不能。synchronized是一种
同步锁,在修饰方法时,需要具体逻辑,而接口只是定义,因为直接修饰接口中的方法没意义,可以用来修饰接口方法的
具体实现。
接口方法能否用static
修饰
这和jdk版本有关。jdk8之前:不能;jdk8新特性: 能。——参见JDK8新特性之接口的静态方法和默认方法
举例
这里提供两种方式:jad反编译和
反射来获取成员变量和方法的相关内容。
jad反编译
下面先给出对应源码,再用jad反编译
.class文件。反编译执行命令如下:
jad -a -o -s java 类名.class
jad详细命令参见反编译小工具:jad常用命令介绍
接口.java源码
MyInterface.java接口源码如下:
public interface MyInterface { String name = "MyInterface"; void add(); }
接口.class反编译
MyInterface.class反编译结果如下:
public interface MyInterface { public abstract void add(); public static final String name = "MyInterface"; }
可以看到,
1.在成员变量(常量)中默认的修饰符是
public static final;
2.在方法中,默认的修饰符是
public abstract
抽象类.java源码
MyAbstract抽象类源码如下:
public abstract class MyAbstract { public String name; void get() { System.out.println("MyAbstract get() "); } // 抽象类中的没有实现的方法必须是“abstract” abstract void delete(); }
抽象类.class反编译
public abstract class MyAbstract { public MyAbstract() { } void get() { System.out.println("MyAbstract get() "); } abstract void delete(); public String name; }
可以看到,成员方法和成员变量和普通类一样,是什么修饰就是什么。
反射获取
这里新建一个MyTest类,
继承抽象类
MyAbstract,并且
实现接口
MyInterface
反射代码
import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; public class MyTest extends MyAbstract implements MyInterface { public static void main(String[] args) { Field[] abstractFields = MyAbstract.class.getDeclaredFields(); Method[] abstractMethods = MyAbstract.class.getDeclaredMethods(); System.out.println("抽象类MyAbstract成员变量反射信息:"); for (Field f : abstractFields) { System.out.println("变量名:" + f.getName()); System.out.println("修饰符:" + Modifier.toString(f.getModifiers())); System.out.println("变量类型:" + f.getType()); } System.out.println(); System.out.println("抽象类MyAbstract成员方法反射信息:"); for (Method m : abstractMethods) { System.out.println("方法名:" + m.getName()); System.out.println("修饰符:" + Modifier.toString(m.getModifiers())); System.out.println("返回类型:" + m.getReturnType() + "\n"); } Field[] interfaceFields = MyInterface.class.getDeclaredFields(); Method[] interfaceMethods = MyInterface.class.getDeclaredMethods(); System.out.println(); System.out.println("接口MyInterface成员变量反射信息:"); for (Field f : interfaceFields) { System.out.println("变量名:" + f.getName()); System.out.println("修饰符:" + Modifier.toString(f.getModifiers())); System.out.println("变量类型:" + f.getType()); } System.out.println(); System.out.println("接口MyInterface成员方法反射信息:"); for (Method m : interfaceMethods) { System.out.println("方法名:" + m.getName()); System.out.println("修饰符:" + Modifier.toString(m.getModifiers())); System.out.println("返回类型:" + m.getReturnType()); } } @Override public void add() { } @Override void delete() { } }
运行结果
抽象类MyAbstract成员变量反射信息: 变量名:name 修饰符:public 变量类型:class java.lang.String 抽象类MyAbstract成员方法反射信息: 方法名:get 修饰符: 返回类型:void 方法名:delete 修饰符:abstract 返回类型:void 接口MyInterface成员变量反射信息: 变量名:name 修饰符:public static final 变量类型:class java.lang.String 接口MyInterface成员方法反射信息: 方法名:add 修饰符:public abstract 返回类型:void
可以看到,和
jad反编译的结果是一样的。
具体的
反射机制请参见另一篇博文反射机制基础解析
相关文章推荐
- 详细解析Java中抽象类和接口的区别 abstract class和interface
- PHP中的 抽象类(abstract class)和 接口(interface)
- java中抽象类(abstract class)和接口(interface)
- 抽象类(abstract class)和接口(interface)有什么异同?
- 接口(interface)vs. 抽象类(abstract class)
- Java 接口(interface)和抽象类(abstract class)区别
- 抽象类(abstract class)和接口(interface)有什么异同?
- 抽象类(abstract class)与接口(interface)的异同
- PHP中的 抽象类(abstract class)和 接口(interface)
- Java - 抽象类(abstract class)和接口(interface)有什么异同?
- 抽象类(abstract class)与接口(interface)之间有什么不同?
- [2014-3-11]JAVA笔记_抽象类(abstract class)、接口(interface)
- 抽象类(abstract class)和接口(Interface)的区别
- [语法]全面理解抽象类(abstract class),抽象方法(abstract method),虚方法(virtual method),接口(interface)
- 比较C#中抽象类(abstract class)和接口(interface)的异同
- 抽象类(abstract class)和接口(interface)有什么异同?
- 《Beginning Java 7》 - 7 - abstract class 抽象类 和 interface 接口
- PHP中的 抽象类(abstract class)和 接口(interface)
- 在谈PHP中的 抽象类(abstract class)和 接口(interface)
- PHP中的 抽象类(abstract class)和 接口(interface) (非原创)