久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

??Java最簡單最全入門基礎(chǔ)知識(二)之Java面向?qū)ο?小白必備--推薦小白收藏)??

 zhulin1028 2021-12-29

寫代碼:

1,明確需求,。我要做什么?

2,分析思路。我要怎么做?1,2,3,。

3,確定步驟。每一個思路部分用到哪些語句,方法,和對象,。

4,代碼實現(xiàn),。用具體的 java 語言代碼把思路體現(xiàn)出來,。

學習新技術(shù)的四點:

1,該技術(shù)是什么?

2,該技術(shù)有什么特點(使用注意):

3,該技術(shù)怎么使用,。demo

4,該技術(shù)什么時候用?test。

如果此文章能幫助到你或者你學到了一點點東西,希望你能給個關(guān)注,、點贊和評論,。期待您的三連。你的關(guān)注,、點贊和評論對我來說就是我寫下去的動力,。


第一章:Java繼承

java 繼承

繼承是所有 OOP 語言和 Java 語言不可缺少的組成部分,。

繼承是 Java 面對對象編程技術(shù)的一塊基石,是面對對象的三大特征之一,也是實現(xiàn)軟件復用的重要手段,繼承可以理解為一個對象從另一個對象獲取屬性的過程。

如果類 A 是類 B 的父類,而類? B 是類 C 的父類,我們也稱類 C 是 A 的子類,類 C 是從類 A 繼承而來的,。在 Java 中,類的繼承是單一繼承,也就是說,一個子類只能擁有一個父類,。

繼承中最常使用的兩個關(guān)鍵字是?extends?和?implements?。

這兩個關(guān)鍵字的使用決定了一個對象和另一個對象是否是 IS-A (是一個)關(guān)系,。

通過使用這兩個關(guān)鍵字,我們能實現(xiàn)一個對象獲取另一個對象的屬性,。

所有 Java 的類均是由 java.lang.Object 類繼承而來的,所以 Object 是所有類的祖先類,而除了 Object 外,所有類必須有一個父類。

通過?extends?關(guān)鍵字可以申明一個類是繼承另外一個類而來的,一般形式如下:

// A.java
public class A {
    private int i;
    protected int j;
 
    public void func() {
 
    }
}
 
// B.java
public class B extends A {
????public int z;

????public void fund(){

????}
????
}

以上的代碼片段說明,類 B 由類 A 繼承而來的,類 B 是類 A 的子類,。而類 A 是 Object 的子類,這里可以不顯示地聲明,。

作為子類,類 B 的實例擁有類 A 所有的成員變量,但對于 private 類型的成員變量類 B 卻沒有訪問權(quán)限,這保障了類 A 的封裝性。


IS-A 關(guān)系

IS-A 就是說:一個對象是另一個對象的一個分類,。

下面是使用關(guān)鍵字?extends?實現(xiàn)繼承,。

public class Animal{
}

public class Mammal extends Animal{
}

public class Reptile extends Animal{
}

public class Dog extends Mammal{
}

基于上面的例子,以下說法是正確的:

  • Animal 類是 Mammal 類的父類。
  • Animal 類是 Reptile 類的父類,。
  • Mammal 類和 Reptile 類是 Animal 類的子類,。
  • Dog 類既是 Mammal 類的子類又是 Animal 類的子類。

分析以上示例中的 IS-A 關(guān)系,如下:

  • Mammal IS-A Animal
  • Reptile IS-A Animal
  • Dog IS-A Mammal

因此 : Dog IS-A Animal

通過使用關(guān)鍵字?extends?,子類可以繼承父類的除 private 屬性外所有的屬性,。

我們通過使用 instanceof 操作符,能夠確定 Mammal IS-A Animal

實例

public class Dog extends Mammal{

   public static void main(String args[]){

      Animal a = new Animal();
      Mammal m = new Mammal();
      Dog d = new Dog();

      System.out.println(m instanceof Animal);
      System.out.println(d instanceof Mammal);
      System.out.println(d instanceof Animal);
   }
}

以上實例編譯運行結(jié)果如下:

true
true
true

介紹完?extends?關(guān)鍵字之后,我們再來看下?implements?關(guān)鍵字是怎樣使用來表示 IS-A 關(guān)系,。

Implements?關(guān)鍵字在類繼承接口的情況下使用, 這種情況不能使用關(guān)鍵字?extends?

實例

public interface Animal {}

public class Mammal implements Animal{
}

public class Dog extends Mammal{
}

instanceof 關(guān)鍵字

可以使用?instanceof?運算符來檢驗 Mammal 和 dog 對象是否是 Animal 類的一個實例,。

interface Animal{}

class Mammal implements Animal{}

public class Dog extends Mammal{
   public static void main(String args[]){

      Mammal m = new Mammal();
      Dog d = new Dog();

      System.out.println(m instanceof Animal);
      System.out.println(d instanceof Mammal);
      System.out.println(d instanceof Animal);
   }
} 

以上實例編譯運行結(jié)果如下:

true
true
true

HAS-A 關(guān)系

HAS-A 代表類和它的成員之間的從屬關(guān)系,。這有助于代碼的重用和減少代碼的錯誤。

例子

public class Vehicle{}
public class Speed{}
public class Van extends Vehicle{
private Speed sp;
} 

Van 類和 Speed 類是 HAS-A 關(guān)系( Van 有一個 Speed ),這樣就不用將 Speed 類的全部代碼粘貼到 Van 類中了,并且 Speed 類也可以重復利用于多個應(yīng)用程序,。

在面向?qū)ο筇匦灾?#xff0c;用戶不必擔心類的內(nèi)部怎樣實現(xiàn),。

Van 類將實現(xiàn)的細節(jié)對用戶隱藏起來,因此,用戶只需要知道怎樣調(diào)用 Van 類來完成某一功能,而不必知道 Van 類是自己來做還是調(diào)用其他類來做這些工作。

Java 只支持單繼承,也就是說,一個類不能繼承多個類,。

下面的做法是不合法的:

public class extends Animal, Mammal{} 

Java 只支持單繼承(繼承基本類和抽象類),但是我們可以用接口來實現(xiàn)(多繼承接口來實現(xiàn)),代碼結(jié)構(gòu)如下:

public class Apple extends Fruit implements Fruit1, Fruit2{}

一般我們繼承基本類和抽象類用?extends?關(guān)鍵字,實現(xiàn)接口類的繼承用?implements?關(guān)鍵字,。

第二章:Java 重寫(Override)與重載(Overload)

重寫 (Override)

重寫是子類對父類的允許訪問的方法的實現(xiàn)過程進行重新編寫!返回值和形參都不能改變。即外殼不變,核心重寫!

重寫的好處在于子類可以根據(jù)需要,定義特定于自己的行為,。

也就是說子類能夠根據(jù)需要實現(xiàn)父類的方法,。

在面向?qū)ο笤瓌t里,重寫意味著可以重寫任何現(xiàn)有方法。實例如下:

class Animal{

   public void move(){
      System.out.println("動物可以移動");
   }
}

class Dog extends Animal{

   public void move(){
      System.out.println("狗可以跑和走");
   }
}

public class TestDog{

   public static void main(String args[]){
      Animal a = new Animal(); // Animal 對象
      Animal b = new Dog(); // Dog 對象

      a.move();// 執(zhí)行 Animal 類的方法

      b.move();//執(zhí)行 Dog 類的方法
   }
}

以上實例編譯運行結(jié)果如下:

動物可以移動
狗可以跑和走

在上面的例子中可以看到,盡管 b 屬于 Animal 類型,但是它運行的是 Dog 類的 move 方法,。

這是由于在編譯階段,只是檢查參數(shù)的引用類型。

然而在運行時,Java 虛擬機 (JVM) 指定對象的類型并且運行該對象的方法,。

因此在上面的例子中,之所以能編譯成功,是因為 Animal 類中存在 move 方法,然而運行時,運行的是特定對象的方法,。

思考以下例子:

class Animal{

   public void move(){
      System.out.println("動物可以移動");
   }
}

class Dog extends Animal{

   public void move(){
      System.out.println("狗可以跑和走");
   }
   public void bark(){
      System.out.println("狗可以吠叫");
   }
}

public class TestDog{

   public static void main(String args[]){
      Animal a = new Animal(); // Animal 對象
      Animal b = new Dog(); // Dog 對象

      a.move();// 執(zhí)行 Animal 類的方法
      b.move();//執(zhí)行 Dog 類的方法
      a.bark();//執(zhí)行 Animal 類的方法
   }
}

以上實例編譯運行結(jié)果如下:

TestDog.java:30: cannot find symbol
symbol  : method bark()
location: class Animal
                a.bark();
                 ^

該程序?qū)伋鲆粋€編譯錯誤,因為 a 的引用類型 Animal 沒有 bark 方法。


方法重寫的規(guī)則

  • 參數(shù)列表與被重寫方法的參數(shù)列表必須完全相同。
  • 返回類型與被重寫方法的返回類型可以不相同,但是必須是父類返回值的派生類(java5 及更早版本返回類型要一樣,java7 及更高版本可以不同),。
  • 子類方法的訪問權(quán)限必須大于或等于父類方法的訪問權(quán)限,。例如:如果父類的一個方法被聲明為 public,那么在子類中重寫該方法就不能聲明為 protected。
  • 父類的成員方法只能被它的子類重寫,。
  • 聲明為 final 的方法不能被重寫,。
  • 聲明為 static 的方法不能被重寫,但是能夠被再次聲明。
  • 子類和父類在同一個包中,那么子類可以重寫父類所有方法,除了聲明為 private 和 final 的方法,。
  • 子類和父類不在同一個包中,那么子類只能夠重寫父類的聲明為 public 和 protected 的非 final 方法,。
  • 重寫的方法能夠拋出任何非強制異常,無論被重寫的方法是否拋出異常。但是,重寫的方法不能拋出新的強制性異常,或者比被重寫方法聲明的更廣泛的強制性異常,反之則可以,。
  • 構(gòu)造方法不能被重寫,。
  • 如果不能繼承一個方法,則不能重寫這個方法,。
  • 訪問權(quán)限不能比父類中被重寫的方法的訪問權(quán)限更低,。例如:如果父類的一個方法被聲明為 public,那么在子類中重寫該方法就不能聲明為 protected。

Super 關(guān)鍵字的使用

當需要在子類中調(diào)用父類的被重寫方法時,要使用 super 關(guān)鍵字,。

class Animal{

   public void move(){
      System.out.println("動物可以移動");
   }
}

class Dog extends Animal{

   public void move(){
      super.move(); // 應(yīng)用super類的方法
      System.out.println("狗可以跑和走");
   }
}

public class TestDog{

   public static void main(String args[]){

      Animal b = new Dog(); //
      b.move(); //執(zhí)行 Dog類的方法

   }
}

以上實例編譯運行結(jié)果如下:

動物可以移動
狗可以跑和走

重載 (Overload)

重載 (overloading) 是在一個類里面,方法名字相同,而參數(shù)不同,。返回類型呢?可以相同也可以不同。

每個重載的方法(或者構(gòu)造函數(shù))都必須有一個獨一無二的參數(shù)類型列表,。

最常用的地方就是構(gòu)造器的重載。

重載規(guī)則

  • 被重載的方法必須改變參數(shù)列表;
  • 被重載的方法可以改變返回類型;
  • 被重載的方法可以改變訪問修飾符;
  • 被重載的方法可以聲明新的或更廣的檢查異常;
  • 方法能夠在同一個類中或者在一個子類中被重載,。
  • 無法以返回值類型作為重載函數(shù)的區(qū)分標準,。

實例

public class Overloading {
 
public int test(){
System.out.println("test1");
return 1;
}
 
public void test(int a){
System.out.println("test2");
}
 
//以下兩個參數(shù)類型順序不同
public String test(int a,String s){
System.out.println("test3");
return "returntest3";
}
 
public String test(String s,int a){
System.out.println("test4");
return "returntest4";
}
 
public static void main(String[] args){
Overloading o = new Overloading();
System.out.println(o.test());
o.test(1);
System.out.println(o.test(1,"test3"));
System.out.println(o.test("test4",1));
}
}

以上實例編譯運行結(jié)果如下:

test1
1
test2
test3
returntest3
test4
returntest4

重寫與重載之間的區(qū)別

區(qū)別點重載方法重寫方法
參數(shù)列表必須修改一定不能修改
返回類型可以修改一定不能修改
異常可以修改可以減少或刪除,一定不能拋出新的或者更廣的異常
訪問可以修改一定不能做更嚴格的限制(可以降低限制)

總結(jié)

方法的重寫 (Overriding) 和重載 (Overloading) 是 java 多態(tài)性的不同表現(xiàn),重寫是父類與子類之間多態(tài)性的一種表現(xiàn),重載可以理解成多態(tài)的具體表現(xiàn)形式。

  • (1)方法重載是一個類中定義了多個方法名相同,而他們的參數(shù)的數(shù)量不同或數(shù)量相同而類型和次序不同,則稱為方法的重載 (Overloading),。
  • (2)方法重寫是在子類存在方法與父類的方法的名字相同,而且參數(shù)的個數(shù)與類型一樣,返回值也一樣的方法,就稱為重寫 (Overriding),。
  • (3)方法重載是一個類的多態(tài)性表現(xiàn),而方法重寫是子類與父類的一種多態(tài)性表現(xiàn)。

第三章? Java多態(tài)

Java 多態(tài)


多態(tài)是同一個行為具有多個不同表現(xiàn)形式或形態(tài)的能力,。

多態(tài)性是對象多種表現(xiàn)形式的體現(xiàn)。

比如我們說"寵物"這個對象,它就有很多不同的表達或?qū)崿F(xiàn),比如有小貓,、小狗,、蜥蜴等等。那么我到寵物店說"請給我一只寵物",服務(wù)員給我小貓,、小狗或者蜥蜴都可以,我們就說"寵物"這個對象就具備多態(tài)性,。

接下來讓我們通過實例來了解Java的多態(tài),。

簡單的例子

public interface Vegetarian{}
public class Animal{}
public class Deer extends Animal implements Vegetarian{}

因為Deer類具有多重繼承,所以它具有多態(tài)性,。以上實例解析如下:

  • 一個 Deer IS-A(是一個) Animal
  • 一個 Deer IS-A(是一個) Vegetarian
  • 一個 Deer IS-A(是一個) Deer
  • 一個 Deer IS-A(是一個)Object

在Java中,所有的對象都具有多態(tài)性,因為任何對象都能通過IS-A測試的類型和Object類,。

訪問一個對象的唯一方法就是通過引用型變量。

引用型變量只能有一種類型,一旦被聲明,引用型變量的類型就不能被改變了,。

引用型變量不僅能夠被重置為其他對象,前提是這些對象沒有被聲明為final,。還可以引用和它類型相同的或者相兼容的對象。它可以聲明為類類型或者接口類型,。

當我們將引用型變量應(yīng)用于Deer對象的引用時,下面的聲明是合法的:

Deer d = new Deer();
Animal a = d;
Vegetarian v = d;
Object o = d;

所有的引用型變量d,a,v,o都指向堆中相同的Deer對象,。


虛方法

我們將介紹在Java中,當設(shè)計類時,被重寫的方法的行為怎樣影響多態(tài)性。

我們已經(jīng)討論了方法的重寫,也就是子類能夠重寫父類的方法,。

當子類對象調(diào)用重寫的方法時,調(diào)用的是子類的方法,而不是父類中被重寫的方法,。

要想調(diào)用父類中被重寫的方法,則必須使用關(guān)鍵字super。

/* 文件名 : Employee.java */
public class Employee
{
   private String name;
   private String address;
   private int number;
   public Employee(String name, String address, int number)
   {
      System.out.println("Constructing an Employee");
      this.name = name;
      this.address = address;
      this.number = number;
   }
   public void mailCheck()
   {
      System.out.println("Mailing a check to " + this.name
       + " " + this.address);
   }
   public String toString()
   {
      return name + " " + address + " " + number;
   }
   public String getName()
   {
      return name;
   }
   public String getAddress()
   {
      return address;
   }
   public void setAddress(String newAddress)
   {
      address = newAddress;
   }
   public int getNumber()
   {
     return number;
   }
}

假設(shè)下面的類繼承Employee類:

/* 文件名 : Salary.java */
public class Salary extends Employee
{
   private double salary; //Annual salary
   public Salary(String name, String address, int number, double
      salary)
   {
       super(name, address, number);
       setSalary(salary);
   }
   public void mailCheck()
   {
       System.out.println("Within mailCheck of Salary class ");
       System.out.println("Mailing check to " + getName()
       + " with salary " + salary);
   }
   public double getSalary()
   {
       return salary;
   }
   public void setSalary(double newSalary)
   {
       if(newSalary >= 0.0)
       {
          salary = newSalary;
       }
   }
   public double computePay()
   {
      System.out.println("Computing salary pay for " + getName());
      return salary/52;
   }
}

現(xiàn)在我們仔細閱讀下面的代碼,嘗試給出它的輸出結(jié)果:

/* 文件名 : VirtualDemo.java */
public class VirtualDemo
{
   public static void main(String [] args)
   {
      Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00);
      Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);
      System.out.println("Call mailCheck using Salary reference --");
      s.mailCheck();
      System.out.println("\n Call mailCheck using Employee reference--");
      e.mailCheck();
    }
}

以上實例編譯運行結(jié)果如下:

Constructing an Employee
Constructing an Employee
Call mailCheck using Salary reference --
Within mailCheck of Salary class
Mailing check to Mohd Mohtashim with salary 3600.0

Call mailCheck using Employee reference--
Within mailCheck of Salary class
Mailing check to John Adams with salary 2400.0

例子中,我們實例化了兩個Salary對象,。一個使用Salary引用s,另一個使用Employee引用,。

編譯時,編譯器檢查到mailCheck()方法在Salary類中的聲明。

在調(diào)用s.mailCheck()時,Java虛擬機(JVM)調(diào)用Salary類的mailCheck()方法,。

因為e是Employee的引用,所以調(diào)用e的mailCheck()方法則有完全不同的結(jié)果,。

當編譯器檢查e.mailCheck()方法時,編譯器檢查到Employee類中的mailCheck()方法。

在編譯的時候,編譯器使用Employee類中的mailCheck()方法驗證該語句, 但是在運行的時候,Java虛擬機(JVM)調(diào)用的是Salary類中的mailCheck()方法,。

該行為被稱為虛擬方法調(diào)用,該方法被稱為虛擬方法,。

Java中所有的方法都能以這種方式表現(xiàn),借此,重寫的方法能在運行時調(diào)用,不管編譯的時候源代碼中引用變量是什么數(shù)據(jù)類型。

多態(tài)的實現(xiàn)方式

方式一:重寫:

這個內(nèi)容已經(jīng)在上一章節(jié)詳細講過,就不再闡述,詳細可訪問:Java 重寫(Override)與重載(Overload),。

方式二:接口

  • 1. 生活中的接口最具代表性的就是插座,例如一個三接頭的插頭都能接在三孔插座中,因為這個是每個國家都有各自規(guī)定的接口規(guī)則,有可能到國外就不行,那是因為國外自己定義的接口類型,。
  • 2. java中的接口類似于生活中的接口,就是一些方法特征的集合,但沒有方法的實現(xiàn)。具體可以看?java接口?這一章節(jié)的內(nèi)容,。

方式三:抽象類和抽象方法

詳情請看?Java 抽象類?章節(jié)

第四章? Java抽象類

Java 抽象類


在 Java 面向?qū)ο蟮母拍钪?#xff0c;所有的對象都是通過類來描繪的,但是反過來,并不是所有的類都是用來描繪對象的,如果一個類中沒有包含足夠的信息來描繪一個具體的對象,這樣的類就是抽象類,。

抽象類除了不能實例化對象之外,類的其它功能依然存在,成員變量、成員方法和構(gòu)造方法的訪問方式和普通類一樣,。

由于抽象類不能實例化對象,所以抽象類必須被繼承,才能被使用,。也是因為這個原因,通常在設(shè)計階段決定要不要設(shè)計抽象類。

父類包含了子類集合的常見的方法,但是由于父類本身是抽象的,所以不能使用這些方法,。


抽象類

在Java語言中使用abstract class來定義抽象類,。如下實例:

/* 文件名 : Employee.java */
public abstract class Employee
{
   private String name;
   private String address;
   private int number;
   public Employee(String name, String address, int number)
   {
      System.out.println("Constructing an Employee");
      this.name = name;
      this.address = address;
      this.number = number;
   }
   public double computePay()
   {
     System.out.println("Inside Employee computePay");
     return 0.0;
   }
   public void mailCheck()
   {
      System.out.println("Mailing a check to " + this.name
       + " " + this.address);
   }
   public String toString()
   {
      return name + " " + address + " " + number;
   }
   public String getName()
   {
      return name;
   }
   public String getAddress()
   {
      return address;
   }
   public void setAddress(String newAddress)
   {
      address = newAddress;
   }
   public int getNumber()
   {
     return number;
   }
}

注意到該Employee類沒有什么不同,盡管該類是抽象類,但是它仍然有3個成員變量,7個成員方法和1個構(gòu)造方法。 現(xiàn)在如果你嘗試如下的例子:

/* 文件名 : AbstractDemo.java */
public class AbstractDemo
{
   public static void main(String [] args)
   {
      /* 以下是不允許的,會引發(fā)錯誤 */
      Employee e = new Employee("George W.", "Houston, TX", 43);

      System.out.println("\n Call mailCheck using Employee reference--");
      e.mailCheck();
    }
}

當你嘗試編譯AbstractDemo類時,會產(chǎn)生如下錯誤:

Employee.java:46: Employee is abstract; cannot be instantiated
      Employee e = new Employee("George W.", "Houston, TX", 43);
                   ^
1 error

繼承抽象類

我們能通過一般的方法繼承Employee類:

/* 文件名 : Salary.java */
public class Salary extends Employee
{
   private double salary; //Annual salary
   public Salary(String name, String address, int number, double
      salary)
   {
       super(name, address, number);
       setSalary(salary);
   }
   public void mailCheck()
   {
       System.out.println("Within mailCheck of Salary class ");
       System.out.println("Mailing check to " + getName()
       + " with salary " + salary);
   }
   public double getSalary()
   {
       return salary;
   }
   public void setSalary(double newSalary)
   {
       if(newSalary >= 0.0)
       {
          salary = newSalary;
       }
   }
   public double computePay()
   {
      System.out.println("Computing salary pay for " + getName());
      return salary/52;
   }
}

盡管我們不能實例化一個Employee類的對象,但是如果我們實例化一個Salary類對象,該對象將從Employee類繼承3個成員變量和7個成員方法,。

/* 文件名 : AbstractDemo.java */
public class AbstractDemo
{
   public static void main(String [] args)
   {
      Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00);
      Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);

      System.out.println("Call mailCheck using Salary reference --");
      s.mailCheck();

      System.out.println("\n Call mailCheck using Employee reference--");
      e.mailCheck();
    }
}

以上程序編譯運行結(jié)果如下:

Constructing an Employee
Constructing an Employee
Call mailCheck using  Salary reference --
Within mailCheck of Salary class
Mailing check to Mohd Mohtashim with salary 3600.0

Call mailCheck using Employee reference--
Within mailCheck of Salary class
Mailing check to John Adams with salary 2400.

抽象方法

如果你想設(shè)計這樣一個類,該類包含一個特別的成員方法,該方法的具體實現(xiàn)由它的子類確定,那么你可以在父類中聲明該方法為抽象方法,。

Abstract關(guān)鍵字同樣可以用來聲明抽象方法,抽象方法只包含一個方法名,而沒有方法體。

抽象方法沒有定義,方法名后面直接跟一個分號,而不是花括號,。

public abstract class Employee
{
   private String name;
   private String address;
   private int number;
   
   public abstract double computePay();
   
   //其余代碼
}

聲明抽象方法會造成以下兩個結(jié)果:

  • 如果一個類包含抽象方法,那么該類必須是抽象類,。
  • 任何子類必須重寫父類的抽象方法,或者聲明自身為抽象類。

繼承抽象方法的子類必須重寫該方法。否則,該子類也必須聲明為抽象類,。最終,必須有子類實現(xiàn)該抽象方法,否則,從最初的父類到最終的子類都不能用來實例化對象,。

如果Salary類繼承了Employee類,那么它必須實現(xiàn)computePay()方法:

/* 文件名 : Salary.java */
public class Salary extends Employee
{
   private double salary; // Annual salary
  
   public double computePay()
   {
      System.out.println("Computing salary pay for " + getName());
      return salary/52;
   }

   //其余代碼
}

第五章 Java封裝

Java 封裝


在面向?qū)ο蟪淌皆O(shè)計方法中,封裝(英語:Encapsulation)是指,一種將抽象性函式接口的實作細節(jié)部份包裝、隱藏起來的方法,。

封裝可以被認為是一個保護屏障,防止該類的代碼和數(shù)據(jù)被外部類定義的代碼隨機訪問,。

要訪問該類的代碼和數(shù)據(jù),必須通過嚴格的接口控制。

封裝最主要的功能在于我們能修改自己的實現(xiàn)代碼,而不用修改那些調(diào)用我們代碼的程序片段,。

適當?shù)姆庋b可以讓程式碼更容易理解與維護,也加強了程式碼的安全性,。

實例

讓我們來看一個java封裝類的例子:

/* 文件名: EncapTest.java */
public class EncapTest{

   private String name;
   private String idNum;
   private int age;

   public int getAge(){
      return age;
   }

   public String getName(){
      return name;
   }

   public String getIdNum(){
      return idNum;
   }

   public void setAge( int newAge){
      age = newAge;
   }

   public void setName(String newName){
      name = newName;
   }

   public void setIdNum( String newId){
      idNum = newId;
   }
}

以上實例中public方法是外部類訪問該類成員變量的入口。

通常情況下,這些方法被稱為getter和setter方法,。

因此,任何要訪問類中私有成員變量的類都要通過這些getter和setter方法,。

通過如下的例子說明EncapTest類的變量怎樣被訪問:

/* F文件名 : RunEncap.java */
public class RunEncap{

   public static void main(String args[]){
      EncapTest encap = new EncapTest();
      encap.setName("James");
      encap.setAge(20);
      encap.setIdNum("12343ms");

      System.out.print("Name : " + encap.getName()+ 
                             " Age : "+ encap.getAge());
    }
}

以上代碼編譯運行結(jié)果如下:

Name : James

第六章 Java接口

Java 接口


接口(英文:Interface),在JAVA編程語言中是一個抽象類型,是抽象方法的集合,接口通常以interface來聲明。一個類通過繼承接口的方式,從而來繼承接口的抽象方法,。

接口并不是類,編寫接口的方式和類很相似,但是它們屬于不同的概念,。類描述對象的屬性和方法。接口則包含類要實現(xiàn)的方法,。

除非實現(xiàn)接口的類是抽象類,否則該類要定義接口中的所有方法,。

接口無法被實例化,但是可以被實現(xiàn)。一個實現(xiàn)接口的類,必須實現(xiàn)接口內(nèi)所描述的所有方法,否則就必須聲明為抽象類,。另外,在Java中,接口類型可用來聲明一個變量,他們可以成為一個空指針,或是被綁定在一個以此接口實現(xiàn)的對象,。

接口與類相似點:

  • 一個接口可以有多個方法。
  • 接口文件保存在.java結(jié)尾的文件中,文件名使用接口名,。
  • 接口的字節(jié)碼文件保存在.class結(jié)尾的文件中,。
  • 接口相應(yīng)的字節(jié)碼文件必須在與包名稱相匹配的目錄結(jié)構(gòu)中。

接口與類的區(qū)別:

  • 接口不能用于實例化對象,。
  • 接口沒有構(gòu)造方法,。
  • 接口中所有的方法必須是抽象方法。
  • 接口不能包含成員變量,除了static和final變量,。
  • 接口不是被類繼承了,而是要被類實現(xiàn),。
  • 接口支持多重繼承。

接口的聲明

接口的聲明語法格式如下:

[可見度] interface 接口名稱 [extends 其他的類名] {
        // 聲明變量
        // 抽象方法
}

Interface關(guān)鍵字用來聲明一個接口,。下面是接口聲明的一個簡單例子,。

/* 文件名 : NameOfInterface.java */
import java.lang.*;
//引入包

public interface NameOfInterface
{
   //任何類型 final, static 字段
   //抽象方法
}

接口有以下特性:

  • 接口是隱式抽象的,當聲明一個接口的時候,不必使用abstract關(guān)鍵字。
  • 接口中每一個方法也是隱式抽象的,聲明時同樣不需要abstract關(guān)鍵子,。
  • 接口中的方法都是公有的,。

實例

/* 文件名 : Animal.java */
interface Animal {

   public void eat();
   public void travel();
}

接口的實現(xiàn)

當類實現(xiàn)接口的時候,類要實現(xiàn)接口中所有的方法。否則,類必須聲明為抽象的類,。

類使用implements關(guān)鍵字實現(xiàn)接口,。在類聲明中,Implements關(guān)鍵字放在class聲明后面,。

實現(xiàn)一個接口的語法,可以使用這個公式:

... implements 接口名稱[, 其他接口, 其他接口..., ...] ...

實例

/* 文件名 : MammalInt.java */
public class MammalInt implements Animal{

   public void eat(){
      System.out.println("Mammal eats");
   }

   public void travel(){
      System.out.println("Mammal travels");
   } 

   public int noOfLegs(){
      return 0;
   }

   public static void main(String args[]){
      MammalInt m = new MammalInt();
      m.eat();
      m.travel();
   }
} 

以上實例編譯運行結(jié)果如下:

Mammal eats
Mammal travels

重寫接口中聲明的方法時,需要注意以下規(guī)則:

  • 類在實現(xiàn)接口的方法時,不能拋出強制性異常,只能在接口中,或者繼承接口的抽象類中拋出該強制性異常。
  • 類在重寫方法時要保持一致的方法名,并且應(yīng)該保持相同或者相兼容的返回值類型,。
  • 如果實現(xiàn)接口的類是抽象類,那么就沒必要實現(xiàn)該接口的方法,。

在實現(xiàn)接口的時候,也要注意一些規(guī)則:

  • 一個類可以同時實現(xiàn)多個接口。
  • 一個類只能繼承一個類,但是能實現(xiàn)多個接口,。
  • 一個接口能繼承另一個接口,這和類之間的繼承比較相似。

接口的繼承

一個接口能繼承另一個接口,和類之間的繼承方式比較相似,。接口的繼承使用extends關(guān)鍵字,子接口繼承父接口的方法,。

下面的Sports接口被Hockey和Football接口繼承:

// 文件名: Sports.java
public interface Sports
{
   public void setHomeTeam(String name);
   public void setVisitingTeam(String name);
}

// 文件名: Football.java
public interface Football extends Sports
{
   public void homeTeamScored(int points);
   public void visitingTeamScored(int points);
   public void endOfQuarter(int quarter);
}

// 文件名: Hockey.java
public interface Hockey extends Sports
{
   public void homeGoalScored();
   public void visitingGoalScored();
   public void endOfPeriod(int period);
   public void overtimePeriod(int ot);
}

Hockey接口自己聲明了四個方法,從Sports接口繼承了兩個方法,這樣,實現(xiàn)Hockey接口的類需要實現(xiàn)六個方法。

相似的,實現(xiàn)Football接口的類需要實現(xiàn)五個方法,其中兩個來自于Sports接口,。


接口的多重繼承

在Java中,類的多重繼承是不合法,但接口允許多重繼承,,。

在接口的多重繼承中extends關(guān)鍵字只需要使用一次,在其后跟著繼承接口。 如下所示:

public interface Hockey extends Sports, Event

以上的程序片段是合法定義的子接口,與類不同的是,接口允許多重繼承,而 Sports及 Event 可能定義或是繼承相同的方法


標記接口

最常用的繼承接口是沒有包含任何方法的接口,。

標識接口是沒有任何方法和屬性的接口.它僅僅表明它的類屬于一個特定的類型,供其他代碼來測試允許做一些事情,。

標識接口作用:簡單形象的說就是給某個對象打個標(蓋個戳),使對象擁有某個或某些特權(quán)。

例如:java.awt.event包中的MouseListener接口繼承的java.util.EventListener接口定義如下:

package java.util;
public interface EventListener
{}

沒有任何方法的接口被稱為標記接口,。標記接口主要用于以下兩種目的:

  • 建立一個公共的父接口:

    正如EventListener接口,這是由幾十個其他接口擴展的Java API,你可以使用一個標記接口來建立一組接口的父接口,。例如:當一個接口繼承了EventListener接口,Java虛擬機(JVM)就知道該接口將要被用于一個事件的代理方案。

  • 向一個類添加數(shù)據(jù)類型:

    這種情況是標記接口最初的目的,實現(xiàn)標記接口的類不需要定義任何接口方法(因為標記接口根本就沒有方法),但是該類通過多態(tài)性變成一個接口類型,。

第七章 Java包

Java 包(package)

為了更好地組織類,Java提供了包機制,用于區(qū)別類名的命名空間,。

包的作用

  • 1 把功能相似或相關(guān)的類或接口組織在同一個包中,方便類的查找和使用。
  • 2 如同文件夾一樣,包也采用了樹形目錄的存儲方式,。同一個包中的類名字是不同的,不同的包中的類的名字是可以相同的,當同時調(diào)用兩個不同包中相同類名的類時,應(yīng)該加上包名加以區(qū)別,。因此,包可以避免名字沖突。
  • 3 包也限定了訪問權(quán)限,擁有包訪問權(quán)限的類才能訪問某個包中的類,。

Java使用包(package)這種機制是為了防止命名沖突,訪問控制,提供搜索和定位類(class),、接口、枚舉(enumerations)和注釋(annotation)等,。

包語句的語法格式為:

package pkg1[.pkg2[.pkg3…]];

例如,一個Something.java 文件它的內(nèi)容

package net.java.util
public class Something{
   ...
}

那么它的路徑應(yīng)該是 net/java/util/Something.java 這樣保存的,。 package(包)的作用是把不同的java程序分類保存,更方便的被其他java程序調(diào)用。

一個包(package)可以定義為一組相互聯(lián)系的類型(類,、接口,、枚舉和注釋),為這些類型提供訪問保護和命名空間管理的功能。

以下是一些Java中的包:

  • java.lang-打包基礎(chǔ)的類
  • java.io-包含輸入輸出功能的函數(shù)

開發(fā)者可以自己把一組類和接口等打包,并定義自己的package,。而且在實際開發(fā)中這樣做是值得提倡的,當你自己完成類的實現(xiàn)之后,將相關(guān)的類分組,可以讓其他的編程者更容易地確定哪些類,、接口、枚舉和注釋等是相關(guān)的,。

由于package創(chuàng)建了新的命名空間(namespace),所以不會跟其他package中的任何名字產(chǎn)生命名沖突,。使用包這種機制,更容易實現(xiàn)訪問控制,并且讓定位相關(guān)類更加簡單,。


創(chuàng)建包

創(chuàng)建package的時候,你需要為這個package取一個合適的名字。之后,如果其他的一個源文件包含了這個包提供的類,、接口,、枚舉或者注釋類型的時候,都必須將這個package的聲明放在這個源文件的開頭。

包聲明應(yīng)該在源文件的第一行,每個源文件只能有一個包聲明,這個文件中的每個類型都應(yīng)用于它,。

如果一個源文件中沒有使用包聲明,那么其中的類,函數(shù),枚舉,注釋等將被放在一個無名的包(unnamed package)中,。

例子

讓我們來看一個例子,這個例子創(chuàng)建了一個叫做animals的包。通常使用小寫的字母來命名避免與類,、接口名字的沖突,。

在animals包中加入一個接口(interface):

/* 文件名: Animal.java */
package animals;

interface Animal {
   public void eat();
   public void travel();
}

接下來,在同一個包中加入該接口的實現(xiàn):

package animals;

/* 文件名 : MammalInt.java */
public class MammalInt implements Animal{

   public void eat(){
      System.out.println("Mammal eats");
   }

   public void travel(){
      System.out.println("Mammal travels");
   } 

   public int noOfLegs(){
      return 0;
   }

   public static void main(String args[]){
      MammalInt m = new MammalInt();
      m.eat();
      m.travel();
   }
} 

然后,編譯這兩個文件,并把他們放在一個叫做animals的子目錄中。 用下面的命令來運行:

$ mkdir animals
$ cp Animal.class  MammalInt.class animals
$ java animals/MammalInt
Mammal eats
Mammal travel

import關(guān)鍵字

為了能夠使用某一個包的成員,我們需要在 Java 程序中明確導入該包,。使用"import"語句可完成此功能,。

在 java 源文件中 import 語句應(yīng)位于 package 語句之后,所有類的定義之前,可以沒有,也可以有多條,其語法格式為:

import package1[.package2…].(classname|*);

如果在一個包中,一個類想要使用本包中的另一個類,那么該包名可以省略。

例子

下面的payroll包已經(jīng)包含了Employee類,接下來向payroll包中添加一個Boss類,。Boss類引用Employee類的時候可以不用使用payroll前綴,Boss類的實例如下,。

package payroll;

public class Boss
{
   public void payEmployee(Employee e)
   {
      e.mailCheck();
   }
}

如果Boss類不在payroll包中又會怎樣?Boss類必須使用下面幾種方法之一來引用其他包中的類

使用類全名描述,例如:

payroll.Employee

用import關(guān)鍵字引入,使用通配符"*"

import payroll.*;

使用import關(guān)鍵字引入Employee類

import payroll.Employee;

注意:

類文件中可以包含任意數(shù)量的import聲明。import聲明必須在包聲明之后,類聲明之前,。


package的目錄結(jié)構(gòu)

類放在包中會有兩種主要的結(jié)果:

  • 包名成為類名的一部分,正如我們前面討論的一樣,。
  • 包名必須與相應(yīng)的字節(jié)碼所在的目錄結(jié)構(gòu)相吻合。

下面是管理你自己java中文件的一種簡單方式:

將類,、接口等類型的源碼放在一個文件中,這個文件的名字就是這個類型的名字,并以.java作為擴展名,。例如:

// 文件名 :  Car.java

package vehicle;

public class Car {
   // 類實現(xiàn)  
}

接下來,把源文件放在一個目錄中,這個目錄要對應(yīng)類所在包的名字。

....\vehicle\Car.java

現(xiàn)在,正確的類名和路徑將會是如下樣子:

  • 類名 -> vehicle.Car

  • 路徑名 -> vehicle\Car.java (in windows)

通常,一個公司使用它互聯(lián)網(wǎng)域名的顛倒形式來作為它的包名.例如:互聯(lián)網(wǎng)域名是apple.com,所有的包名都以com.apple開頭,。包名中的每一個部分對應(yīng)一個子目錄,。

例如:這個公司有一個com.apple.computers的包,這個包包含一個叫做Dell.java的源文件,那么相應(yīng)的,應(yīng)該有如下面的一連串子目錄:

....\com\apple\computers\Dell.java

編譯的時候,編譯器為包中定義的每個類、接口等類型各創(chuàng)建一個不同的輸出文件,輸出文件的名字就是這個類型的名字,并加上.class作為擴展后綴,。 例如:

// 文件名: Dell.java

package com.apple.computers;
public class Dell{
      
}
class Ups{
      
}

現(xiàn)在,我們用-d選項來編譯這個文件,如下:

$javac -d . Dell.java

這樣會像下面這樣放置編譯了的文件:

.\com\apple\computers\Dell.class.\com\apple\computers\Ups.class

你可以像下面這樣來導入所有 \com\apple\computers\中定義的類,、接口等:

import com.apple.computers.*;

編譯之后的.class文件應(yīng)該和.java源文件一樣,它們放置的目錄應(yīng)該跟包的名字對應(yīng)起來。但是,并不要求.class文件的路徑跟相應(yīng)的.java的路徑一樣,。你可以分開來安排源碼和類的目錄,。

<path-one>\sources\com\apple\computers\Dell.java
<path-two>\classes\com\apple\computers\Dell.class

這樣,你可以將你的類目錄分享給其他的編程人員,而不用透露自己的源碼。用這種方法管理源碼和類文件可以讓編譯器和java虛擬機(JVM)可以找到你程序中使用的所有類型,。

類目錄的絕對路徑叫做class path,。設(shè)置在系統(tǒng)變量CLASSPATH中。編譯器和java虛擬機通過將package名字加到class path后來構(gòu)造.class文件的路徑,。

<path- two>\classes是class path,package名字是com.apple.computers,而編譯器和JVM會在 <path-two>\classes\com\apple\compters中找.class文件,。

一個class path可能會包含好幾個路徑。多路徑應(yīng)該用分隔符分開,。默認情況下,編譯器和JVM查找當前目錄,。JAR文件按包含Java平臺相關(guān)的類,所以他們的目錄默認放在了class path中,。


設(shè)置CLASSPATH系統(tǒng)變量

用下面的命令顯示當前的CLASSPATH變量:

  • Windows平臺(DOS 命令行下)-> C:\> set CLASSPATH
  • UNIX平臺(Bourne shell下)-> % echo $CLASSPATH

刪除當前CLASSPATH變量內(nèi)容:

  • Windows平臺(DOS 命令行下)-> C:\> set CLASSPATH=
  • UNIX平臺(Bourne shell下)-> % unset CLASSPATH; export CLASSPATH

設(shè)置CLASSPATH變量:

  • Windows平臺(DOS 命令行下)-> set CLASSPATH=C:\users\jack\java\classes
  • UNIX平臺(Bourne shell下)-> % CLASSPATH=/home/jack/java/classes; export CLASSPATH

本文參考https://www./java,如若侵權(quán)請私信刪除。

    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多