abstract關鍵字
abstract:抽象的,可以用來修飾類和方法,當abstract修飾類的時候,該類就叫抽象類,修飾方法時,就叫抽象方法。
什麼叫抽象類
在java中,因為繼承,使得類越來越具體化,類的設計使得父類越來越通用,在類的設計裡應該保證父類和子類能夠共享特徵,有時候就把父類設計的非常抽象,讓它沒有具體的例項。這樣的類就叫抽象類,例如人可以說話,但是不同的人可能說的話不一樣,所以讓說話的內容由子類自己決定。
1.抽象類不可以被例項化,例項化應該是它的子類來完成
public class TestAbstract {
public static void main(String[] args) {
Person person = new Person();
person.eat();
}
}
class Person{
public void eat(){
System.out.println("人吃飯");
}
public void walk(){
System.out.println("人走路");
}
}
class Teacher extends Person{
public void eat(){
System.out.println("教師吃飯");
}
public void walk(){
System.out.println("教師走路");
}
}
class Student extends Person{
public void eat(){
System.out.println("學生吃飯");
}
public void walk(){
System.out.println("學生走路");
}
}
複製程式碼
從上述程式碼可以看出,如果Person類沒有被abstract修飾,在main方法裡是可以被例項化的,如果我們加上了abstract關鍵字修飾,那麼Person person = new Person();就會被報錯。
2.抽象類是類的一種,也有構造器
很神奇的是,抽象類不能被例項化,但是卻可以存在構造器,
abstract class Person{
String name;
int age;
public void eat(){
System.out.println("人吃飯");
}
public void walk(){
System.out.println("人走路");
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Person() {
super();
}
}
複製程式碼
3.抽象方法所在的類一定是抽象類
abstract class Person{
public abstract void eat();
public abstract void walk();
}
複製程式碼
abstract修飾方法
abstract修飾的方法也叫抽象方法,關於抽象方法需要說明以下幾點:
1.抽象方法的格式,沒有方法體,就是不包括{},例如public abstract void eat();
2.抽象方法值保留方法的功能,具體的實現過程由繼承他的子類來實現,
3.如果子類繼承了抽象類沒有全部實現父類抽象方法,則表明子類還是一個抽象類,也必須用abstract修飾類,
4.如果子類繼承了抽象類,並且全部重寫了父類抽象方法,則該子類就可以被例項化。
4.抽象類中可以沒有抽象方法
abstract class Person{
public void eat(){
System.out.println("人吃飯");
}
public void walk(){
System.out.println("人走路");
}
}
複製程式碼
5.抽象方法必須由子類來重寫
abstract class Person{
public abstract void eat();
public abstract void walk();
}
class Teacher extends Person{
public void eat(){
System.out.println("教師吃飯");
}
public void walk(){
System.out.println("教師走路");
}
}
複製程式碼
從上述程式碼也能得出,子類繼承一個抽象類,要麼全部實現父類的抽象方法,要麼本身還是一個抽象類。
6.子類中的抽象方法不能和父類的抽象方法同名
7.abstract不能與final修飾同一個類,原因很簡單,final修飾的類不能被繼承,
8.abstract不能與private,static,final,native並列修飾同一個方法
這三點大家都可以試試,道理也很簡單。下面一個例子說明抽象類的相關知識;
public class TestAbstract {
public static void main(String[] args) {
Person p1 = new Teacher();
p1.eat();
Person p2 = new Student();
p2.eat();
Teacher t1 = new Teacher();
t1.eat();
Student s1 = new Student();
s1.eat();
}
}
abstract class Person{
public abstract void eat();
public abstract void walk();
}
class Teacher extends Person{
public void eat(){
System.out.println("教師吃飯");
}
public void walk(){
System.out.println("教師走路");
}
}
class Student extends Person{
public void eat(){
System.out.println("學生吃飯");
}
public void walk(){
System.out.println("學生走路");
}
}
複製程式碼
結果為:
教師吃飯
學生吃飯
教師吃飯
學生吃飯
複製程式碼
模板方法設計模式
抽象類體現的就是一種模板設計模式,抽象類作為多個子類通用的模板,子類在抽象類的基礎上進行擴充套件,這種模式解決的就是一部分功能不確定,就把不確定的功能部分暴露出去,讓子類自己去實現。
案例
public class TestTemplate {
public static void main(String[] args) {
new subTemplate().spendTime();
}
}
abstract class Template{
public abstract void testAbstract();
public void spendTime(){
long start = System.currentTimeMillis();
this.testAbstract();
long end = System.currentTimeMillis();
System.out.println("執行testAbstract方法花費的時間為"+(end-start));
}
}
class subTemplate extends Template{
@Override
public void testAbstract() {//求10000以內的素數
boolean flag = false;
for(int i = 2; i <= 10000;i++){
for(int j = 2;j <=Math.sqrt(i);j++){
if(i % j == 0){
flag = true;
break;
}
}if(!flag){
System.out.println(i);
}
flag = false;
}
}
}
複製程式碼
介面
介面是一種比抽象類還抽象的東西,它不是類,不能被例項化,只能例項化他的子類。使用關鍵字interface,實現介面的類就必須實現介面中的所有方法,這個在javaee中的三層架構中會經常使用。在使用介面的過程中需要注意一下幾點:
1.一個類可以實現多個介面,也可以繼承其他介面。
2.介面中只能有常量和抽象方法。
3.介面的許可權只能是public,你可以手動宣告為其他,編譯就會報錯。
4.介面中定義的“成員變數”,也加不可變的常量,因為會自動加上public static final,可以通過介面名.常量名進行訪問。
5.介面主要用於定義規範,接觸耦合關係
public interface TestInterface {
public void show();
public void updateEmployee();
}
複製程式碼
這就是一個介面,只是說介面沒有太多說的,主要是介面有什麼用,java為什麼會提供這麼一個東西,介面在JAVAEE中使用很多,例如Mybatis基於介面的mapper開發。JavaEE三層模式開發都會大量使用介面。下面主要學習介面的應用。
介面的多型性
public class Test {
public static void main(String[] args) {
Duck duck = new Duck();
Test.test1(duck);
Test.test2(duck);
Test.test3(duck);
}
public static void test1(Swim s){
s.swim();
}
public static void test2(Runner r){
r.runner();
}
public static void test3(Fly f){
f.fly();
}
}
interface Swim{
public abstract void swim();
}
interface Runner{
public abstract void runner();
}
interface Fly{
public abstract void fly();
}
class Duck implements Swim,Fly,Runner{
@Override
public void runner() {
System.out.println("鴨子跑起來了");
}
@Override
public void fly() {
System.out.println("鴨子飛起來了");
}
@Override
public void swim() {
System.out.println("鴨子游起來了");
}
}
複製程式碼
繼承的多型是子類重寫父類方法,父類引用指向不同的子類例項,就會呼叫對應子類的方法,從而執行不同的響應,
介面的多型是實現類實現多個介面,方法引數列表裡可以帶介面的引用引數,方法的具體可以通過介面引用呼叫介面裡的抽象方法,呼叫該方法時傳入介面實現類,實際執行的是實現類中的方法。這是相同的例項,不同的介面體現的多型性。
介面應用-工廠方法的設計模式
定義一個用於建立物件的介面,讓子類決定例項化哪一個類。簡單來講就是暴露介面給使用者,根據使用者傳入的引數返回特定的例項物件的一種模式。
例如:一個生產汽車的工廠,有很多分廠,生產火車的,生產轎車的,生產貨車的,使用者不知道有這些分廠,使用者只知道有一個工廠可以生產車,這個工廠是虛擬的,使用者在介面傳入編號,由工廠返回使用者指定的車例項。
案例如下:
public class TestFactory {
public static void main(String[] args) {
IWorkFactory factory = new StudentWorkFactory();
factory.getWork().doWork();
IWorkFactory factory2 = new TeacherWorkFactory();
factory2.getWork().doWork();
}
}
interface IWorkFactory{
Work getWork();
}
class StudentWorkFactory implements IWorkFactory{
@Override
public Work getWork() {
return new StudentWork();
}
}
class TeacherWorkFactory implements IWorkFactory{
@Override
public Work getWork() {
return new TeacherWork();
}
}
interface Work{
void doWork();
}
class StudentWork implements Work{
@Override
public void doWork() {
System.out.println("學生寫作業");
}
}
class TeacherWork implements Work{
@Override
public void doWork() {
System.out.println("教師批改作業");
}
}
複製程式碼
抽象類和介面的區別
總的來說:抽象類和介面都不能被例項化,但是都可以定義抽象類和介面的引用。
1.抽象類可以有抽象方法,也可以有方法的具體實現,介面中不能。
2.抽象類中的成員修飾可以為private,預設,protected,public但是介面中只能為public。
3.抽象類可以定義成員變數,但是介面中其實都是不可變的常量。
抽象類如下:
abstract class TestAbstractDemo{
String name;
abstract void test1();
void test2(){
System.out.println("我是具體方法");
}
}
複製程式碼
介面如下:
interface TestInterfaceDemo{
String name="Hello";
abstract void test1();
abstract void test2();
}
複製程式碼
總結:
程式設計中,什麼時候使用介面,什麼時候使用抽象類,這是一個架構的難點,只有對問題充分了解才能選擇合適的設計方法,抽象類在java中表示的是一種繼承關係,一個子類只存在一個父類,但是卻可以實現多個介面。