Java: 面向對象程序設計(下)

1. 類的繼承java

繼承的意義:編程

當一個類A繼承了一個已存在的類B後,類A就用於了類B全部的非private的屬性和方法,但同時類A還能夠根據須要,添加新的方法和屬性。函數

在Java語言中,一個類能夠擁有多個子類,可是一個子類只能擁有一個父類。優化

 

如何定義子類:this

class 子類名 extends 父類名spa

{}code

public class ExtendsDemo1 {
    Employee e;
    Manager m;
    
    public ExtendsDemo1()
    {
        e=new Employee("Wnag Xiao Yue", 3000.00, "2005/05/20");
        System.out.println("Name: "+ e.getName() + "; Salary: "+ e.getSalary()+ "; Hireday: "+e.getHireDay()+"\n");
        
        m=new Manager("Zhao XS", 8000.00, "2004/6/2", 4000.00, 20);
        System.out.println("Name: "+ m.getName() + "; Salary: "+ m.getSalary()+ "; Hireday: "+m.getHireDay() + "; Bonus: "+m.getBonus()+"; Holidays: "+m.getHolidays());
        
    }

    public static void main(String[] args) {
        new ExtendsDemo1();

    }

}

class Employee{
    String name;
    double salary;
    String hireDay;
    
    public Employee(String name, double salary, String hireDay)
    {
        this.name=name;
        this.salary=salary;
        this.hireDay=hireDay;
        System.out.println("I'm Employee");
    }
    
    public String getName()
    {
        return name;
    }
    public String getHireDay()
    {
        return hireDay;
    }
    public double getSalary()
    {
        return salary;
    }
}

class Manager extends Employee{
    private double bonus;
    private int holidays;
    
    public Manager(String name, double salary, String hireDay, double bonus, int holidays)
    {
        super(name, salary, hireDay);   //調用父類構造方法
        this.bonus=bonus;
        this.holidays=holidays;
        System.out.println("I'm Manager");
    }
    
    public double getBonus()
    {
        return bonus;
    }
    
    public int getHolidays()
    {
        return holidays;
    }
}

I'm Employee
Name: Wnag Xiao Yue; Salary: 3000.0; Hireday: 2005/05/20對象

I'm Employee
I'm Manager
Name: Zhao XS; Salary: 8000.0; Hireday: 2004/6/2; Bonus: 4000.0; Holidays: 20blog

 

覆蓋父類中的方法(重載:方法名、參數、返回值均不變, 只有方法體發生了變化):繼承

public class ExtendsDemo1 {
    Employee e;
    Manager m;
    
    public ExtendsDemo1()
    {
        e=new Employee("Wnag Xiao Yue", 3000.00, "2005/05/20");
        e.getInfo();
        System.out.println("Name: "+ e.getName() + "; Salary: "+ e.getSalary()+ "; Hireday: "+e.getHireDay()+"\n");
        
        m=new Manager("Zhao XS", 8000.00, "2004/6/2", 4000.00, 20);
        m.getInfo();
        System.out.println(m.getSalary());
        System.out.println("Name: "+ m.getName() + "; Hireday: "+m.getHireDay() + "; Bonus: "+m.getBonus()+"; Holidays: "+m.getHolidays());
        
    }

    public static void main(String[] args) {
        new ExtendsDemo1();

    }

}

class Employee{
    String name;
    double salary;
    String hireDay;
    
    public Employee(String name, double salary, String hireDay)
    {
        this.name=name;
        this.salary=salary;
        this.hireDay=hireDay;
    }
    
    public void getInfo()
    {
        System.out.println("I'm Eployee");
    }
    public String getName()
    {
        return name;
    }
    public String getHireDay()
    {
        return hireDay;
    }
    public double getSalary()
    {
        return salary;
    }
}

class Manager extends Employee{
    private double bonus;
    private int holidays;
    
    public Manager(String name, double salary, String hireDay, double bonus, int holidays)
    {
        super(name, salary, hireDay);   //調用父類構造方法
        this.bonus=bonus;
        this.holidays=holidays;
    }
    
    public void getInfo()
    {
        System.out.println("I'm Manager");
    }
    public double getSalary()
    {
        System.out.print("Manager Salary is: ");
        return salary;
    }
    public double getBonus()
    {
        return bonus;
    }
    
    public int getHolidays()
    {
        return holidays;
    }
}

I'm Eployee
Name: Wnag Xiao Yue; Salary: 3000.0; Hireday: 2005/05/20

I'm Manager
Manager Salary is: 8000.0
Name: Zhao XS; Hireday: 2004/6/2; Bonus: 4000.0; Holidays: 20

 

this關鍵字的使用:

this關鍵字就好像建立一個虛擬的類對象實例,在定義類的時候,就提早使用其對象實例。

注意:因爲this是指向當前類實例的一個引用,所以只能在實例方法的定義中使用。而在類方法(static型靜態方法)中,不能使用this關鍵字。

public class ThisDemo {
    private String name;
    
    public ThisDemo(String name)
    {
        this.name=name;
    }
    
    public String getName()
    {
        return name;
    }
    
    public void show()
    {
        String str=this.getName();
        System.out.println(str);
    }
    
    public Object getObject()
    {
        return this;
    }

}

 

super的使用:

子類繼承父類後,若要在子類中直接調用父類的構造方法,就必須使用super(...)語句,注意一下兩點:

  • 若要在子類構造方法中調用父類構造方法,super()語句必須放在子類構造方法中的第一行;
  • 不能在子類構造方法中同時調用this(...)和super(...)語句,由於這兩條語句都必須位於子類構造方法中的第一行

 

2. 抽象類與接口

抽象類和抽象方法:

abstract關鍵字是抽象修飾符,只能用於修飾類和方法。

  • 抽象類:沒有具體實例對象的類。簡單的說,抽象類就是一種通過優化的概念組織方式,把所要描述的事物的共性抽象出來,使得全部的概念井井有條、簡潔
  • 抽象方法:在定義的時候只有方法的聲明,而沒有方法體的實現部分。也就是說,抽象方法僅包含訪問修飾符、返回類型、方法名及參數表,而不包含方法體「{}」中的內容。至於方法的實現部分,須要在繼承該抽象方法的子類中,進行定義。

概括總結後,使用抽象類和抽象方法要注意一下4點:

  • abstract抽象類不能建立對象,必須經過子類繼承後,有子類來建立對象
  • abstract抽象方法只容許方法聲明,不容許方法實現
  • abstract抽象類中,能夠沒有抽象方法,也能夠有一個或多個抽象方法
  • 若一個類中含有abstract抽象方法,那麼這個類必須被聲明爲抽象類
public class AbstractDemo {
    Employee1 e;
    
    public AbstractDemo()
    {
        e=new Employee1("Wnag Xiao Yue", 3000.00, "2005/05/20", 24);
        e.getInfo();
        System.out.println("Age: "+e.getAge());
        System.out.println("Name: "+ e.getName() + "; Salary: "+ e.getSalary()+ "; Hireday: "+e.getHireDay()+"\n");
    }

    public static void main(String[] args) {
        new AbstractDemo();

    }

}

abstract class People{
    String name;
    int age;
    
    abstract String getName();
    abstract int getAge();
}

class Employee1 extends People{
    double salary;
    String hireDay;
    
    public Employee1(String name, double salary, String hireDay, int age)
    {
        this.name=name;
        this.salary=salary;
        this.hireDay=hireDay;
        this.age=age;
    }
    
    public void getInfo()
    {
        System.out.println("I'm Eployee");
    }
    public String getName()
    {
        return name;
    }
    public int getAge()
    {
        return age;
    }
    public String getHireDay()
    {
        return hireDay;
    }
    public double getSalary()
    {
        return salary;
    }
}

I'm Eployee
Age: 24
Name: Wnag Xiao Yue; Salary: 3000.0; Hireday: 2005/05/20

 

什麼是接口:

Java語言中的接口不一樣於通常的類,一般稱爲接口類,是用來描述類的功能的。在接口類中,定義了抽象的方法和常量,造成一個屬性集合,該屬性集合表明了一組功能的實現。在Java語言中,一個類只能繼承自一個父類;可是一個類能夠實現多個接口,所以使用接口主要是爲了實現類的多重繼承功能。

 

如何定義接口:

[public] interface 接口名 [extends 父類接口]

{

  //藉口體

  //常量聲明

  [public] [static] [final] 常量類型 常量名 =  常量值;

 

  //抽象方法聲明

  [public] [abstract] 返回類型 方法名(參數列表) [throw 異常列表]

}

 

在定義接口類的時候須要注意一下幾點:

  • 與定義類類似,定義的接口類也具備繼承性。定義一個接口的時候,能夠經過extends關鍵字來讓定義的接口繼承自一個已經存在的父類接口
  • 接口體由兩部分組成,一部分是對接口屬性的聲明,另外一部分是對接口中方法的聲明。接口中的屬性都是用final修飾的常量;而接口中的方法都是用abstract修飾的抽象方法,在接口類中,只能給出這些抽象方法的方法名、返回值、參數列表,而不能定義方法體
  • 根據編程的習慣,接口類的名字,通常都已大寫字母「I」開頭
public interface IEmployee
{
    public static final double prize=1000.00;

    public abstract void addSalary();
}

 

實現接口:

在定義好接口後,就能夠建立一個類來實現該接口類,同時在實現類中,完成接口類中抽象方法的定義。

public class UseIEmployee {
    Employee2 e;
    
    public UseIEmployee()
    {
        e=new Employee2("Wnag Xiao Yue", 3000.00, "2005/05/20");
        e.addSalary(2);
        e.getInfo();
        System.out.println("Name: "+ e.getName() + "; Salary: "+ e.getSalary()+ "; Hireday: "+e.getHireDay()+"\n");
    }
    

    public static void main(String[] args) {
        new UseIEmployee();

    }

}

class Employee2 implements IEmplyee1{
    private String name;
    private double salary;
    private String hireDay;
    
    public Employee2(String name, double salary, String hireDay)
    {
        this.name=name;
        this.salary=salary;
        this.hireDay=hireDay;
    }
    
    public String getName()
    {return name;}
    
    public void getInfo()
    {System.out.println("I'm Employee");}
    
    public double getSalary()
    {return salary;}
    
    public String getHireDay()
    {
        return hireDay;
    }
    
    public void addSalary(int n)
    {
        salary+=prize*n;
    }
}

interface IEmplyee1 {
    
    public static final double prize = 1000.00;
    public abstract void addSalary(int n);

}

I'm Employee
Name: Wnag Xiao Yue; Salary: 5000.0; Hireday: 2005/05/20

 

3. 內部類和匿名類

什麼是內部類:

內部類就是定義在其餘類內部的類,而內部類所在的類通常稱爲外部類。根據內部類在外部類中所處的位置,通常又分爲定義在方法體的內部類以及定義在方法體外的成員內部類。同時,定義在方法體內的內部類又能夠分爲兩種,分別是有實例名稱的內部類和無實例名稱的匿名內部類。

 

如何使用內部類:

(1)對於定義在方法體外的內部類(成員內部類)

又能夠分爲如下兩種狀況:

  • 定義在方法體外的成員內部類:如同其餘類成員同樣,也是附屬於類的,能夠經過外部類的實例來引用,即先建立一個外部類的實例,再經過該外部類的對象實例來建立內部類實例。語法格式有如下兩種

new 外部類構造方法().內部類構造方法();

外部類對象實例.new 內部類構造方法();

public class InnerClassDemo1 {
    
    private String s="World";
    
    class InnerClass{
         public InnerClass()
         {
             System.out.println("This is Inner Class constructor");
         }
         
         //內部類對象可以訪問其所在外部類的所有屬性,包括私有屬性
         public void showMessage(String str)
         {
             System.out.println("Hello "+s+","+str);
         }
    }

    public static void main(String[] args) {
        InnerClass i1=new InnerClassDemo1().new InnerClass();
        i1.showMessage("Lilian");
        System.out.println();
        
        InnerClassDemo1 demo=new InnerClassDemo1();
        InnerClass i2=demo.new InnerClass();
        i2.showMessage("Kira");

    }

}

This is Inner Class constructor
Hello World,Lilian

This is Inner Class constructor
Hello World,Kira

  • 對於靜態內部類的引用:靜態內部類的附屬於外部類的,而不附屬於外部類的實例,所以不須要經過外部類的對象實例來建立內部類對象,直接經過外部類名就能夠實現。語法格式以下:

new 外部類名.內部構造方法();

 

public class InnerClassDemo2 {
    
    private static String s= "World";
    
    static class InnerClass{
        public InnerClass()
        {
            System.out.println("This is inner class constructor");
        }
        
        public void showMessage(String str)
        {
            System.out.println("Hello "+ s  +","+str);
        }
    }

    public static void main(String[] args) {
        InnerClass i=new InnerClassDemo2.InnerClass();
        i.showMessage("Lilian");

    }

}

This is inner class constructor
Hello World,Lilian

 

(2)對於定義在方法體內的內部類

因爲附屬於方法體,因此只能在方法體中建立對象實例,而且建立的實例也只能在方法體中被訪問。所建立的對象實例的生命週期與方法體相同,當方法結束後,對象也就隨之消失。

public class InnerClassDemo3 {
    private String str="World";
    
    public InnerClassDemo3()
    {
        showMessage();
    }
    
    public void showMessage()
    {
        System.out.println("Now you are in method!");
        
        class InnerClass{
            public InnerClass()
            {
                System.out.println("This is inner class constructor");
            }
            
            public void showMesage()
            {
                System.out.println("Hello "+ str+"!");
            }
        }
        
        InnerClass i=new InnerClass();
        i.showMesage();
        
        System.out.println("Method end!");
    }

    public static void main(String[] args) {
        new InnerClassDemo3();

    }

}

Now you are in method!
This is inner class constructor
Hello World!
Method end!

 

什麼是匿名類

在建立類的對象的時候,會有兩種方式,第一種方式是建立對象後,將該對象保存在一個對象變量中,以下所示。

類名 對象名 = new 類構造方法();

另外一種方式就是所謂的匿名類方式建立對象。使用匿名類方式建立對象時,並不將建立的對象保存在對象變量中,程序會根據建立對象的構造方法中的操做,來運行程序,當程序運行結束後,該對象的生命週期也就結束了。

new 類構造方法();

 

使用內部類須要注意的問題:

  • Java程序中,對於內部類的繼承沒有限制,與普通的類一致,知足單繼承。同時對內部類的嵌套層次也沒有限制
  • 同通常類同樣,能夠實現接口
  • 非靜態的內部類能夠看做是外部類中的普通方法,對整個類具備訪問權限,能夠訪問其所在外部類的全部屬性。包括private私有屬性。可是非靜態的內部類中不能包含static類型的屬性。非靜態的內部類能夠被不一樣訪問修飾符修飾,也能夠被其餘外部類的成員函數訪問。
  • 靜態內部類能夠看做是外部類中的static方法,只能訪問聲明爲static的變量,以及調用static的方法
  • 定義在方法體中的內部類,能夠看做是方法中的局部變量,能夠訪問外部類中的全部屬性,包括private私有屬性
  • 定義在方法體中的內部類,能夠訪問許哦在方法中被聲明爲final型的局部變量
  • 定義在方法體中的內部類,不能用承認訪問修飾符修飾,同時也不能使用static修飾符修飾

 

實戰練習:

簡單模擬一個僱員工資管理的程序系統。整個系統由5個源文件組成:

  • IEmployee.java接口類,在其中定義常量prize,用來保存員工加薪的基本值,同時在接口類中聲明addSalary()抽象方法,用來聲明給員工加薪的方法
public interface IEmployee {
    
    public static final double prize=1000.00;
    public abstract void addSalary(); 

}
  • People.java抽象類,用來描述人的屬性
abstract class People {
    String name;
    int age;
    
    abstract String getName();
    abstract int getAge();

}
  • Employee.java僱員類,用來表示一個特定的員工。該類繼承了People抽象類,同時實現了IEmployee接口,並在類方法體中定義了三個成員方法,用來獲取僱員屬性
public class Employee extends People implements IEmployee{
    double salary;
    String hireDay;
    
    public Employee(String name, double salary, String hireDay, int age)
    {
        this.name=name;
        this.salary=salary;
        this.hireDay=hireDay;
        this.age=age;
    }
    
    public void getInfo()
    {
        System.out.println("I'm Employee");
    }
    public double getSalary()
    {
        return salary;
    }
    public String getHireDay()
    {
        return hireDay;
    }
    
    //實現父類中的方法
    public String getName()
    {return name;}
    
    public int getAge()
    {return age;}
    
    //實現接口中的方法
    public void addSalary()
    {
        salary+=prize;
    }

}
  • Manager.jave經理類,該類繼承了Employee僱員類,同時在Manager類中,使用方法重載從新定義getInfo(), getSalary(), addSalary()方法
public class Manager extends Employee{
    private double bonus;
    private int holidays;
    
    public Manager(String name, double salary, String hireDay, int age, int holidays)
    {
        super(name, salary, hireDay, age);
        this.holidays=holidays;
    }
    
    public void getInfo()
    {
        System.out.println("I'm Manager");
    }
    public double getSalary()
    {
        return salary;
    }
    
    public int getHolidays()
    {return holidays;}
    
    public void addSalary()
    {
        salary+=prize*2;
    }

}
  • ManageEmployeeSalary.java程序主類,包含main方法,是本系統中全部程序的入口點,用來全局控制和運行整個系統
public class ManageEmployeeSalary {
    Employee e1, e2;
    Manager m;
    
    public ManageEmployeeSalary()
    {
        e1=new Employee("Wang Xiao Yue", 3000.00, "2005/05/20", 24);
        e2=new Employee("Xu Guang Yang", 2000.00, "2006/06/02", 22);
        m=new Manager("Zhao XS", 8000.00, "2004/6/2", 26, 20);
        
        System.out.println("name:"+e1.getName());
        e1.getInfo();
        System.out.println("Age:"+e1.getAge());
        System.out.println("Salary:"+e1.getSalary());
        System.out.println("Hireday:"+e1.getHireDay()+"\n");
        
        System.out.println("name:"+e2.getName());
        e2.getInfo();
        System.out.println("Age:"+e2.getAge());
        System.out.println("Salary:"+e2.getSalary());
        System.out.println("Hireday:"+e2.getHireDay()+"\n");
        
        System.out.println("name:"+m.getName());
        m.getInfo();
        System.out.println("Age:"+m.getAge());
        System.out.println("Salary:"+m.getSalary());
        System.out.println("Hireday:"+m.getHireDay()+"\n");
        
        e1.addSalary();
        e2.addSalary();
        m.addSalary();
        System.out.println("\nAfter adding salary:");
        System.out.println(e1.getName()+"'s salary is:"+e1.getSalary());
        System.out.println(e2.getName()+"'s salary is:"+e2.getSalary());
        System.out.println(m.getName()+"'s salary is:"+m.getSalary());
        
    }

    public static void main(String[] args) {
        new ManageEmployeeSalary();
        

    }

}

name:Wang Xiao Yue
I'm Employee
Age:24
Salary:3000.0
Hireday:2005/05/20

name:Xu Guang Yang
I'm Employee
Age:22
Salary:2000.0
Hireday:2006/06/02

name:Zhao XS
I'm Manager
Age:26
Salary:8000.0
Hireday:2004/6/2

After adding salary:Wang Xiao Yue's salary is:4000.0Xu Guang Yang's salary is:3000.0Zhao XS's salary is:10000.0

相關文章
相關標籤/搜索