天天看點

Java學習筆記(七):抽象類、内部類和匿名内部類

一、抽象類

什麼叫抽象方法呢?

在所有的普通方法上面都會有一個“{}”,這個表示方法體,有方法體的方法一定可以被對象直接使用。

而抽象方法,是指沒有方法體的方法,同時抽象方法還必須使用關鍵字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檔案:

Java學習筆記(七):抽象類、内部類和匿名内部類

額外生成了一個名為“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();
	}
}
           

實質上我們生成了一個沒有機會命名的類,是以這個類為匿名類;

它不能再産生其他對象,但是它會生成相應的類檔案;

Java學習筆記(七):抽象類、内部類和匿名内部類

匿名内部類的優點:

1.不需要明确的生成派生類,對于簡單問題,明顯提高程式設計效率

2.在需要時臨時産生匿名内部類,實作抽象方法,這樣更靈活

3.一個匿名内部類對應一種抽象方法的實作,這樣更緊湊