Java學習筆記之抽象類與介面的應用
1、抽象類的實際應用 — 定義模板
假設有這樣的場景,將人分為工人和學生,兩者都能說話,只是說話的內容不一樣,換句話說,說話這個功能應該是一個具體功能,說話的內容由學生和工人決定,我們可以用抽象類實現這個場景
abstract class Person2{
private String name;
private int age;
public Person2(String name, int age){
this.name = name;
this.age = age;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
public void say(){
System.out.println(this.getContent());
}
public abstract String getContent();
}
class Student2 extends Person2{
private String school;
public Student2(String name,int age, String school){
super(name, age);
this.setSchool(school);
}
public void setSchool(String school){
this.school = school;
}
public String getSchool() {
return school;
}
public String getContent(){
return "姓名:" + super.getName() + " 年齡:" + super.getAge() + " 學校:" + getSchool();
}
}
class Worker2 extends Person2{
private float salary;
public Worker2(String name, int age, float salary){
super(name, age);
this.salary = salary;
}
public void setSalary(float salary) {
this.salary = salary;
}
public double getSalary() {
return salary;
}
@Override
public String getContent() {
return "姓名:" + super.getName() + " 年齡:" + super.getAge() + " 收入:" + getSalary();
}
}
public class AbstractClassAppDemo {
public static void main(String[] args) {
Student2 stu = new Student2("張三", 20, "NKU");
Worker2 wk = new Worker2("李四",30,8000.0f);
stu.say();
wk.say();
}
}
// 執行結果:
姓名:張三 年齡:20 學校:NKU
姓名:李四 年齡:30 收入:8000.0
2、介面的實際應用 — 制定標準
介面在實際生活中更多的是用來制定標準的,比如U盤和印表機都可以插在電腦上使用,這是因為他們都實現了USB介面,對於電腦來說,只要符合USB介面標準的裝置都可以插入使用。
interface USB{
public void start();
public void stop();
}
class Computer{
public static void plugin(USB usb){
usb.start();
System.out.println("============ USB 裝置工作 ===========");
usb.stop();
}
}
class Flash implements USB{
public void start(){ // 覆寫方法
System.out.println("U盤開始工作");
}
public void stop(){
System.out.println("U盤結束工作");
}
}
class Print implements USB{
public void start() {
System.out.println("印表機開始工作");
}
public void stop() {
System.out.println("印表機結束工作");
}
}
public class AbstractClassAppDemo {
public static void main(String[] args) {
// Student2 stu = new Student2("張三", 20, "NKU");
// Worker2 wk = new Worker2("李四",30,8000.0f);
// stu.say();
// wk.say();
Computer.plugin(new Flash());
Computer.plugin(new Print());
}
}
// 執行結果:
U盤開始工作
============ USB 裝置工作 ===========
U盤結束工作
印表機開始工作
============ USB 裝置工作 ===========
印表機結束工作
3、工廠設計模式
工廠設計模式是Java裡最常見的一種設計模式,我們來看一下這段程式碼
interface Fruit{ // 定義一個水果介面
public void eat(); // 吃水果
}
class Apple implements Fruit{
public void eat(){
System.out.println("** eat apple!")
}
}
class Orange implements Fruit{
public void eat(){
System.out.println("** eat orange!")
}
}
public class InterfaceDemo{
public static void main(String args[]){
Fruit f = new Apple(); // 例項化介面
f.eat();
}
}
思考:
上面的程式碼是否有問題?
可以看到,程式碼的邏輯沒有問題,只是這樣的設計是否合理呢?主方法我們理解為客戶端,主方法裡程式碼自然是越少越好,我們看到在主方法裡直接指定了要操作的子類,如果要更換子類,就必須修改客戶端,也就是說客戶端和子類是耦合的。
interface Fruit{ // 定義一個水果介面
public void eat(); // 吃水果
}
class Apple implements Fruit{
public void eat(){
System.out.println("** eat apple!")
}
}
class Orange implements Fruit{
public void eat(){
System.out.println("** eat orange!")
}
}
class Factory{ // 定義工廠類
public static Fruit getInstance(String className){
Fruit f = null;
if("apple".equals(className)){
f = new Apple();
}
if("orange".equals(className)){
f = new Orange();
}
return f;
}
}
public class InterfaceDemo{
public static void main(String args[]){
Fruit f = Factory.getInstance(args[0]); // 例項化介面
if(f!=null){ // 判斷是否獲取例項
f.eat();
}
}
}
4、代理設計模式
代理設計模式也是Java裡用的比較多的一種設計模式,所謂的代理設計就是指用代理主題來操作真實主題,真實主題執行具體的業務操作,而代理主題則負責其它業務相關的處理。最常見的就是找代理上網,客戶端通過網路代理連線網路,由代理伺服器完成使用者許可權,訪問限制等與上網相關的操作,
interface Network{
public void browser();
}
class Real implements Network{
public void browser(){
System.out.println("上網瀏覽資訊");
}
}
class Proxy implements Network{
private Network network;
public Proxy(Network network){
this.network = network;
}
public void check(){
System.out.println("檢查使用者是否合法。");
}
public void browser(){
this.check();
this.network.browser(); // 呼叫真實的主題操作
}
}
public class ProxyDemo{
public static void main(String args[]){
Network nw = new Proxy(new Real); // 設定代理操作
nw.browser(); // 客戶只關心一個上網操作
}
}
5、介面卡設計
介面卡設計在圖形介面上用的非常多。
對於一個Java程式,如果一個類要實現一個介面,必須覆寫接口裡的全部抽象方法, 但是有一些抽象方法可能在類裡並沒有用到,這樣全部實現其實會增加許多工作量,因此需要一箇中間過渡類,但是此過渡類又不希望被直接使用,所以將過渡類定為抽象類比較合適,即一個介面首先被一個抽象類(也叫介面卡類)繼承,並在此抽象類中實現若干抽象方法,以後的子類直接繼承此抽象類,就可以有選擇的覆寫所需要的抽象方法。
interface Window{ // 定義window介面,表示視窗操作
public void open(); // 開啟
public void close(); // 關閉
public void activated(); // 視窗活動
public void iconified(); // 視窗最小化
public void deiconified(); // 恢復視窗大小
}
abstract class WindowAdapter implements Window{
public void open(){}; // 開啟
public void close(){}; // 關閉
public void activated(){}; // 視窗活動
public void iconified(){}; // 視窗最小化
public void deiconified(){}; // 恢復視窗大小
}
class WindowImp extends WindowAdapter{
public void open(){
System.out.println("視窗開啟")
}
public void close(){
System.out.println("視窗關閉")
}
}
public class WindowAdapterDemo{
public static void main(String args[]){
Window window = new WindowImp();
window.open();
window.close();
}
}
6、總結
重要:
在開發中,一個類永遠不要去繼承一個已經實現的類,要麼實現介面,要麼繼承抽象類,如果介面和抽象類同時可以使用,優先使用介面,避免單繼承侷限。