一、抽象類
什麼叫抽象方法呢?
在所有的普通方法上面都會有一個“{}”,這個表示方法體,有方法體的方法一定可以被對象直接使用。
而抽象方法,是指沒有方法體的方法,同時抽象方法還必須使用關鍵字abstract做修飾。
而擁有抽象方法的類就是抽象類,抽象類要使用abstract關鍵字聲明。
隻有覆寫了抽象類中所有的抽象方法後,其子類才可以建立對象。否則該子類還是一個抽象類
package stu.crayue.about_abstract.core;
/**
* @author Crayue
* @version 2019年10月31日 下午4:27:32
*/
public abstract class Shape {
protected String name;
public Shape(String name) {
this.name=name;
}
public abstract double perimeter();//求周長
public abstract double area();//求面積
@Override
public String toString() {
return ("圖形為"+name);
}
}
上述代碼中,用abstract關鍵字聲明Shape類為抽象類
還定義了兩個抽象方法求周長和面積
要注意的是:
抽象類不能直接執行個體化,因為抽象類存在未實作的方法;
下面來看在Shape類基礎上派生出來的Square類
package stu.crayue.about_abstract.core;
/**
* @author Crayue
* @version 2019年10月31日 下午4:34:19
*/
public class Square extends Shape {
private double length;
public Square(double length) {
super("正方形");
this.length=length;
}
public double getLength() {
return length;
}
public void setLength(double length) {
this.length = length;
}
@Override
public double perimeter() {
return 4*length;
}
@Override
public double area() {
return length*length;
}
}
再看Rectangle類:
package stu.crayue.about_abstract.core;
/**
* @author Crayue
* @version 2019年10月31日 下午4:38:51
*/
public class Rectangle extends Shape {
private double height;
private double width;
public Rectangle(double height,double width) {
super("長方形");
this.height=height;
this.width=width;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
@Override
public double perimeter() {
return 2*width+2*height;
}
@Override
public double area() {
return width*height;
}
}
再看Circle類:
package stu.crayue.about_abstract.core;
/**
* @author Crayue
* @version 2019年10月31日 下午4:41:39
*/
public class Circle extends Shape {
private double radius;
public Circle(double radius) {
super("圓形");
this.radius=radius;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
@Override
public double perimeter() {
return 2*Math.PI*radius;
}
@Override
public double area() {
return Math.PI*radius*radius;
}
}
最後給一個Demo類:
package stu.crayue.about_abstract.demo;
import stu.crayue.about_abstract.core.Circle;
import stu.crayue.about_abstract.core.Rectangle;
import stu.crayue.about_abstract.core.Square;
/**
* @author Crayue
* @version 2019年10月31日 下午4:44:09
*/
public class Demo {
public static void main(String[] args) {
Square square=new Square(4.0);
System.out.println(square+"周長:"+square.perimeter());
System.out.println(square+"面積:"+square.area());
Rectangle rectangle= new Rectangle(3.0, 4.0);
System.out.println(rectangle+"周長:"+rectangle.perimeter());
System.out.println(rectangle+"面積:"+rectangle.area());
Circle circle=new Circle(2.0);
System.out.println(circle+"周長:"+circle.perimeter());
System.out.println(circle+"面積:"+circle.area());
}
}
運作結果為:
圖形為正方形周長:16.0
圖形為正方形面積:16.0
圖形為長方形周長:14.0
圖形為長方形面積:12.0
圖形為圓形周長:12.566370614359172
圖形為圓形面積:12.566370614359172
抽象類程式設計核心思想:
抽象類由”确定的成分“和”不确定的成分“構成;
”确定的成分“通常由那些類中固定的,固有的和确定的成員、方法構成;
”不确定的成分“是那些類彼此相同,又不同的成分。相同點在于,這些類都存在這些成分;不同點在于,這些成分的具體實作方法不同。
二、内部類
在一個類中,可以定義其他類,這些類稱為内部類;
需要注意的是:
1.在内部類的方法中,可以直接引用外部類的所有成員與方法,并且不受權限修飾符的限制;
2.外部類可以定義内部類對象的成員;
給出一個outclass類:
package com.mec.about_inner.core;
public class OuterClass {
private int privateMember;
protected int protectedMember;
public int publicMember;
public OuterClass() {
//這裡定義三種不同的權限修飾符的成員
privateMember = 1;
protectedMember = 2;
publicMember = 3;
}
//這裡定義三種不同的權限修飾符的方法
private void privateFun() {
System.out.println("privateMember:" + privateMember);
}
protected void protectedFun() {
privateFun();
System.out.println("protectedMember:" + protectedMember);
}
public void publicFun() {
privateFun();
System.out.println("publicMember:" + publicMember);
}
public class InnerClass {
private int innerMember;
public InnerClass() {
innerMember = 4;
}
private void InnerFun() {
privateMember++;
protectedMember++;
publicMember++;
privateFun();
protectedFun();
publicFun();
System.out.println("innerMember:" + innerMember);
}
}
//外部類可以定義其内部類對象的成員
private InnerClass innerObject;
public void fun() {
//外部類可以執行個體化該成員,并且可根據内部類的對象,引用内部類的成員和方法
innerObject = new InnerClass();
innerObject.InnerFun();
System.out.println(innerObject.innerMember++);
}
}
内部類對應的class檔案:
額外生成了一個名為“OuterClass$InnerClass”class檔案
就表明這個類是在OuterClass類中的内部類InnerClass類
三、匿名内部類
首先給出一個簡單的抽象類:
package stu.crayue.about_abstract.core;
/**
* @author Crayue
* @version 2019年10月31日 下午5:28:00
*/
public abstract class Bird {
private String name;
public Bird(String name) {
this.name = name;
}
public abstract String cry();
public void print( ) {
System.out.println( name + "的叫聲:" + cry());
}
}
抽象類不能直接執行個體化,我們試着非執行個體化下:
package stu.crayue.about_abstract.demo;
import stu.crayue.about_abstract.core.Bird;
/**
* @author Crayue
* @version 2019年10月31日 下午5:29:14
*/
public class Test {
public static void main(String[] args) {
Bird jiujiu = new Bird("百靈鳥") {
@Override
public String cry() {
return "啾啾啾啾";
}
};
jiujiu.print();
//第二種手段的展示
new Bird("嘤嘤怪") {
@Override
public String cry() {
return "嘤嘤嘤";
}
}.print();
}
}
實質上我們生成了一個沒有機會命名的類,是以這個類為匿名類;
它不能再産生其他對象,但是它會生成相應的類檔案;
匿名内部類的優點:
1.不需要明确的生成派生類,對于簡單問題,明顯提高程式設計效率
2.在需要時臨時産生匿名内部類,實作抽象方法,這樣更靈活
3.一個匿名内部類對應一種抽象方法的實作,這樣更緊湊