抽象クラスと抽象メソッド
定義
- 抽象メソッドとクラスは抽象キーワードを変更する必要があります。
- 抽象--abstractは、抽象クラスのメソッドは、必ずしも抽象的ではなく、クラスに現れなければならない抽象メソッドは抽象クラスです。
//抽象方法,没有方法体(即没有{}),只有声明
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("继承抽象类");
}
}
- サブクラスは実装する抽象クラスが、抽象親クラスではないかもしれないすべてのそれ以外の場合は、抽象メソッドを抽象型として定義する必要があります。(コードは、方法I、下のコメントそのサブクラスを書き換えた後、エラーが抽象的またはimplentment抽象メソッドを宣言する必要がありますされます )
そしてポイントに通常のクラスと注意を払うの違い:
-
抽象クラスは、抽象クラスは、一例として、直接インスタンス化することができないことを除いて、一般的なカテゴリと同様に、直接延びている、ことも可能であるサブクラスであってもよく、サブクラスは、メソッドオーバーライドすることによって達成される- 抽象的アプローチのセットは、サブクラスが達成できるようにすることですそれ以外の場合は無意味。
-
通常の方法との違い
-
フィールド抽象変形を使用することができない、ローカル変数を変更するために使用することができない、すなわち、変数抽象的ではない、いかなる抽象フィールドらの請求;抽象缶は、コンストラクタ、抽象ないコンストラクタを修正するために使用されていない抽象クラスコンストラクタのみ通常定義されていませんコンストラクタ。
抽象クラスの役割
-
「Javaで考えます "
-
抽象クラスは、クラスとインタフェースとの間の一般的な節度あります。
-
抽象メソッド、抽象クラス抽象クラスは、彼らとのコンパイラを使用する方法をユーザーに伝え、片付けることができます。
-
一方、抽象クラスは後半のツール、仕事をリファクタリング良いですが、あなたは再利用性を達成することができます。
-
-
テンプレートの効果を反映し、抽象クラスのようなサブクラス感の同様のグループは、標準を提供し、サブクラスが元の基底に拡張することができるから抽出されました。
-
抽象父类可以只定义需要使用的某些方法,把不能实现的部分抽象成抽象方法,就是一中留给下一代去实现,一开始没有能力去实现,那可就给厉害的人去做,留给其子类去实现。
接口
定义
- 特殊的“抽象类”——接口(interface):比抽象类更加抽象的是接口,在接口中所有的方法都是抽象的。就不能像上面的抽象类一样还可以有普通方法。
//省略public就变为默认级别,只能在当前包所访问
public interface Figure {
//接口中静态成员变量
String name = "几何图形";//省略public static final
// 绘制几何图形方法
void onDraw(); //省略public 这里是抽象方法
}
- Java中可以implements多个接口,多继承的含义便是接入多个接口(继承只能单继承)
- 一个类可以实现一个或多个接口,继承使用extends关键字(但接口只能继承接口),实现则使用implements关键字。
示例
- JieKou.java
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();
}
- 使用接口的Java代码
//访问了其它包的接口,就是下面这个地址
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);
}
}
注意
- 接口与抽象类一样都不能被实例化
- 实现接口时接口中原有的抽象方法在实现类中必须实现。默认方法可以根据需要有选择实现(覆盖)。静态方法不需要实现,实现类中不能拥有接口中的静态方法。(Java 8之后)
//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 修饰符也是静态常量。抽象类与普通类一样各种形式的成员变量都可以声明。
相同
- 都不能直接实例化来使用。
- 接口和抽象类都可以包含抽象方法,实现接口或继承抽象类的普通子类都必须实现这些抽象方法。
使用场景
-
想要多重继承的时候——接口(功能性强,规范性)
-
想要底层基础功能模块不断改变——抽象类(模板设计)