//抽象方法,没有方法体(即没有{}),只有声明 abstract void f();
/** * @author yhy * 用来完成9.2的练习 * 验证抽象类与抽象方法的使用 */ public class YanZheng { public static void main(String[] args) { // 不能被实例化,抽象类,会报错 // ChouXiang chouxi = new ChouXiang() ; // 可以实例child类 // 即通过继承其子类来实现不能继承抽象类 Child test = new Child(); } } abstract class AbstractChouXiang{ /** * 构造函数 */ AbstractChouXiang() { } /** * 定义一个抽象类的抽象方法 */ abstract void chouxiang(); } class Child extends AbstractChouXiang{ Child(){ System.out.println("实例时候就打印出来"); } /** * 注意这里不是abstract就不要讲方法定义为abstract */ @Override void chouxiang(){ System.out.println("继承抽象类"); } }
抽象类也是可以与普通类那样,可以直接extends,区别在于抽象类不能直接实例化,可以通过实例化其子类,通过子类重写方法实现等—— 设置抽象方法就是让子类来实现的,否则毫无意义。
与普通方法的区别
抽象方法和空方法体的方法不是同一个概念。例如,public abstract void test();是一个抽象方法,它根本没方法体,即方法定义后面没有一对花括号;但public void test(){}方法是一个普通方法,它已经定义了方法体,只是方法体为空,即它的方法体什么也不做,因此这个方法不可使用abstract来修饰。——疯狂的Java讲义
abstract不能用于修饰Field,不能用于修饰局部变量,即没有抽象变量、没有抽象Field等说法;abstract也不能用于修饰构造器,没有抽象构造器, 抽象类里定义的构造器只能是普通构造器 。
《thinking in java》
抽象类是普通的类与接口之间的一种中庸之道。
抽象方法、抽象类可以使类的抽象性明确起来,告诉用户和编译器怎么使用它们;
同时,抽象类是很好的重构工具,在后期的工作中,可以实现重用性。
体现一种模板的效果,从一群相似的子类提炼出一个抽象类的感觉一样,提供了一种规范,子类可以在其原来的基础上进行扩展。
抽象父类可以只定义需要使用的某些方法,把不能实现的部分抽象成抽象方法,就是一中留给下一代去实现,一开始没有能力去实现,那可就给厉害的人去做,留给其子类去实现。
//省略public就变为默认级别,只能在当前包所访问 public interface Figure { //接口中静态成员变量 String name = "几何图形";//省略public static final // 绘制几何图形方法 void onDraw(); //省略public 这里是抽象方法 }
import java.text.SimpleDateFormat; /** * @author yhy * 这个是实现接口定义的代码,在其它地方去调用 * 这里的接口不用public的话,其它的包就访问不了 */ public interface JieKou { // 定义了两个常量 /** * 这里定义一个df变量来获取当前时间 */ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式 String AUTHOR = "yhycoder"; /** * 定义一个接口的方法 * 这里的public是多余的,在接口里面是自动为public */ /*public*/ void print(); }
//访问了其它包的接口,就是下面这个地址 import music.daima.ebook.JieKou; import java.util.Date; public class UseInterfaces { public static void main(String[] args) { //实例化using类,实现查看代码的运行情况 Using Shuchu = new Using(); Shuchu.print(); } } /** * 这里是接口继承接口 */ interface Jiekou2 extends JieKou{ String num = "接口2"; } /** * 这里是Using类实现了JieKou和Jiekou2接口,逗号隔开 */ class Using implements JieKou,Jiekou2 { /** * 重写了方法,调用接口定义的常量 */ @Override public void print() { System.out.println(AUTHOR+"在新的包里面使用接口的时间:"+df.format(new Date())+" 同时还有"+num); } }
//InterfaceA.java文件,定义一个接口 public interface InterfaceA { //抽象方法 void methodA(); String methodB(); // 默认方法 default int methodC() { return "6666"; } // 默认方法 default String methodD() { return "这是默认方法"; } // 静态方法 static double methodE() { return 0.0; } }
实现接口代码
import xxxx.InterfaceA; public class ABC implements InterfaceA { //重写 @Override public void methodA() { } @Override public String methodB() { return "实现methodB方法..."; } //重写覆盖,根据自己的需要来。 @Override public int methodC() { return 500; } } //实现类中不能有接口中的静态方法,最后一行 public class HelloWorld { public static void main(String[] args) { //声明接口类型,对象是实现类,发生多态 InterfaceA abc = new ABC(); // 访问实现类methodB方法 System.out.println(abc.methodB()); // 访问默认方法methodC System.out.println(abc.methodC()); // 访问默认方法methodD System.out.println(abc.methodD()); // 访问InterfaceA静态方法methodE,这里不能通过实现类去使用接口的静态方法,只能通过接口名调用 System.out.println(InterfaceA.methodE()); } }
接口interface,实现接口则使用implements; 抽象类abstract
抽象类可以有普通方法。Java 8 之前 接口 中只有抽象方法,而 Java 8 之后接口中也可以声明具体方法,具体方法通过声明默认方法实现。
和类继承相似,子接口扩展某个父接口,将会获得父接口里定义的 所有 抽象方法、常量Field、内部类和枚举类定义。
实现父接口的所有:一个类实现了一个或多个接口之后,这个类 必须完全实现 这些接口里所定义的全部抽象方法(也就是重写这些抽象方法);否则,该类将保留从父接口那里继承到的抽象方法,该类也必须定义成抽象类。
接口定义的是一种 规范 ,因此接口里不能包含构造器和初始化块定义。接口里可以包含Field(只能是常量)、方法(只能是抽象实例方法)、内部类(包括内部接口、枚举)定义。但 抽象类 与普通类一样,可以有构造器,初始化模块等。
接口只有常量—— 接口 中不能有实例成员变量,接口所声明的成员变量全部是静态常量,即便是变量不加 public static final 修饰符也是静态常量。 抽象类 与普通类一样各种形式的成员变量都可以声明。
想要多重继承的时候——接口(功能性强,规范性)
想要底层基础功能模块不断改变——抽象类(模板设计)
才疏学浅,不对的地方多多指教!
博客园的小伙伴
也是园内小伙伴