欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中的包、抽象類、接口詳解(最新整理)

 更新時間:2025年02月27日 09:59:46   作者:新綠MEHO  
文章介紹了Java中的包、抽象類、接口以及實現(xiàn)多個接口的概念,包用于組織類,避免命名沖突,抽象類用于定義不能被實例化的類,可以包含抽象方法,接口則定義了一組抽象方法,可以被類實現(xiàn),實現(xiàn)多個接口可以實現(xiàn)類似多繼承的效果,感興趣的朋友一起看看吧

包 (package) 是組織類的一種方式, 使用包的主要目的是保證類的唯一性. 例如 , 你在代碼中寫了一個 Test 類 . 然后你的同事也可能寫一個 Test 類 . 如果出現(xiàn)兩個同名的類 , 就會沖突 , 導(dǎo)致代碼不能編譯通過.

導(dǎo)入包

Java 中已經(jīng)提供了很多現(xiàn)成的類供我們使用 . 例如

public class Test {
    public static void main(String[] args) {
        java.util.Date date = new java.util.Date();
        // 得到一個毫秒級別的時間戳
        System.out.println(date.getTime());
   }
}

可以使用 java.util.Date 這種方式引入 java.util 這個包中的 Date 類 . 但是這種寫法比較麻煩一些 , 可以使用 import 語句導(dǎo)入包 . 如果需要使用 java.util 中的其他類 , 可以使用 import java.util.* 但是我們更建議顯式的指定要導(dǎo)入的類名 . 否則還是容易出現(xiàn)沖突的情況

注意事項 : import 和 C++ 的 #include 差別很大 . C++ 必須 #include 來引入其他文件內(nèi)容 , 但是 Java 不需要 . import 只是為了寫代碼的時候更方便 . import 更類似于 C++ 的 namespace 和 using

靜態(tài)導(dǎo)入

使用 import static 可以導(dǎo)入包中的靜態(tài)的方法和字段。

import static java.lang.System.*;
public class Test {
    public static void main(String[] args) {
        out.println("hello");
   }
}

 使用這種方式可以更方便的寫一些代碼, 例如

import static java.lang.Math.*;
public class Test {
    public static void main(String[] args) {
        double x = 30;
        double y = 40;
        // 靜態(tài)導(dǎo)入的方式寫起來更方便一些. 
        // double result = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
        double result = sqrt(pow(x, 2) + pow(y, 2));
        System.out.println(result);
   }
}

將類放入包

基礎(chǔ)規(guī)則

在文件的最上方加上一個 package 語句指定該代碼在哪個包中 . 包名需要盡量指定成唯一的名字 , 通常會用公司的域名的顛倒形式 ( 例如 com.bit.demo1 ). 包名要和代碼路徑相匹配 . 例如創(chuàng)建 com.bit.demo1 的包 , 那么會存在一個對應(yīng)的路徑 com/bit/demo1 來存儲代碼. 如果一個類沒有 package 語句 , 則該類被放到一個默認(rèn)包中 .

常見的系統(tǒng)包

1. java.lang: 系統(tǒng)常用基礎(chǔ)類 (String 、 Object), 此包從 JDK1.1 后自動導(dǎo)入。
2. java.lang.reflect:java 反射編程包 ;
3. java.net: 進行網(wǎng)絡(luò)編程開發(fā)包。
4. java.sql: 進行數(shù)據(jù)庫開發(fā)的支持包。
5. java.util: 是 java 提供的工具程序包, ( 集合類等 )。 
6. java.io:I/O 編程開發(fā)包。

抽象類

語法規(guī)則

像這種沒有實際工作的方法, 我們可以把它設(shè)計成一個 抽象方法 (abstract method) , 包含抽象方法的類我們稱為 抽象類(abstract class)。

abstract class Shape {
        abstract public void draw();
}
在 draw 方法前加上 abstract 關(guān)鍵字 , 表示這是一個抽象方法 . 同時抽象方法沒有方法體 ( 沒有 { }, 不能執(zhí)行具體代碼). 對于包含抽象方法的類 , 必須加上 abstract 關(guān)鍵字表示這是一個抽象類 .

總結(jié) 

1.抽象類是被abstract修飾的
2.被abstract修飾的方法稱為抽象方法,該方法可以沒有具體的實現(xiàn)。

3.當(dāng)一個類中含有抽象方法的時候,該類必須使用abstract修飾

4.抽象類當(dāng)中可以有和普通類一樣的成員變量和一樣的成員方法

5.抽象類是不可以被實例化的。
6.抽象類既然不能實例化對象那么要抽象類干什么???就是為了被繼承。
7.當(dāng)一個普通的類繼承了這個抽象類之后,這個普通類一定要重寫這個抽象類當(dāng)中所有的抽象方法。

8.final和abstract是不同同時存在的,抽象方法不能被private和static修飾!
9.當(dāng)一個抽象類A不想被一個普通類B繼承,此時可以把B這個類變成抽象類,那么再當(dāng)一個普通類C繼承這個抽象類B之后,C要重寫B(tài)和A里面所有的抽象方法。 

注意事項:

1) 抽象類不能直接實例化

Shape shape = new Shape(); 
// 編譯出錯
Error:(30, 23) java: Shape是抽象的; 無法實例化

2) 抽象方法不能是 private 的

abstract class Shape { 
     abstract private void draw(); 
} 
// 編譯出錯
Error:(4, 27) java: 非法的修飾符組合: abstract和private

3) 抽象類中可以包含其他的非抽象方法 , 也可以包含字段 . 這個非抽象方法和普通方法的規(guī)則都是一樣的 , 可以被重寫 , 也可以被子類直接調(diào)用

abstract class Shape { 
 abstract public void draw(); 
     void func() { 
     System.out.println("func"); 
 } 
} 
class Rect extends Shape { 
     ... 
} 
public class Test { 
 public static void main(String[] args) { 
     Shape shape = new Rect(); 
     shape.func(); 
 } 
} 
// 執(zhí)行結(jié)果
func

4)抽象類不一定有抽象方法,但有抽象方法的類一定是抽象類。

5)抽象類中可以有構(gòu)造方法,供子類創(chuàng)建對象時,初始化父類的成員變量。

抽象類的作用

抽象類存在的最大意義就是為了被繼承 . 抽象類本身不能被實例化 , 要想使用 , 只能創(chuàng)建該抽象類的子類 . 然后讓子類重寫抽象類中的抽象方法 .

接口

接口是抽象類的更進一步 . 抽象類中還可以包含非抽象方法 , 和字段 . 而接口中包含的方法都是抽象方法 , 字段只能包含靜態(tài)常量。

語法規(guī)則

interface IShape { 
     void draw(); 
} 
class Cycle implements IShape { 
     @Override 
     public void draw() { 
         System.out.println("○"); 
     } 
} 
public class Test { 
     public static void main(String[] args) { 
         IShape shape = new Rect(); 
         shape.draw(); 
     } 
}

1.使用 interface 定義一個接口
2.接口中的方法一定是抽象方法 , 因此可以省略 abstract
3.接口中的方法一定是 public, 因此可以省略 public
4.Cycle 使用 implements 繼承接口 . 此時表達(dá)的含義不再是 " 擴展 ", 而是 " 實現(xiàn) "
5.在調(diào)用的時候同樣可以創(chuàng)建一個接口的引用 , 對應(yīng)到一個子類的實例 .
6.接口不能單獨被實例化

接口中只能包含抽象方法. 對于字段來說, 接口中只能包含靜態(tài)常量(final static).

interface IShape { 
     void draw(); 
     public static final int num = 10; 
}

 其中的 public, static, final 的關(guān)鍵字都可以省略. 省略后的 num 仍然表示 public 的靜態(tài)常量。

總結(jié)

1.使用interface來定義一個接口
⒉.接口當(dāng)中的成員變量默認(rèn)是public static final的,一般情況下我們不寫

3.接口當(dāng)中的成員方法默認(rèn)是public abstact ,一般情況下我們不寫

4.接口當(dāng)中不可以有普通的方法。
5.Java8開始允許在接口當(dāng)中定義一個default方法,可以有具體的實現(xiàn)的

6.接口當(dāng)中的方法如果是static修飾的方法那么是可以有具體的實現(xiàn)的

7.接口不能通過new關(guān)鍵字進行實例化。
8.類和接口之間可以通過關(guān)鍵字implements來實現(xiàn)接口。

9.接口也可以發(fā)生向上轉(zhuǎn)型和動態(tài)綁定的。
10.當(dāng)一個類實現(xiàn)接口當(dāng)中的方法之后,當(dāng)前類當(dāng)中的方法不能不加public

11.接口當(dāng)中不能有構(gòu)造方法和代碼塊。
12.一個接口也會產(chǎn)生獨立的字節(jié)碼文件。

實現(xiàn)多個接口

有的時候我們需要讓一個類同時繼承自多個父類. 這件事情在有些編程語言通過 多繼承 的方式來實現(xiàn)的。然而 Java 中只支持單繼承, 一個類只能 extends 一個父類. 但是可以同時實現(xiàn)多個接口, 也能達(dá)到多繼承類似的效果.
現(xiàn)在我們通過類來表示一組動物. 

class Animal { 
     protected String name; 
     public Animal(String name) { 
         this.name = name; 
     } 
}

另外我們再提供一組接口 , 分別表示 " 會飛的 ", " 會跑的 ", " 會游泳的”。

interface IFlying { 
     void fly(); 
} 
interface IRunning { 
     void run(); 
} 
interface ISwimming { 
     void swim(); 
}

接下來我們創(chuàng)建幾個具體的動物 貓 , 是會跑的 .

class Cat extends Animal implements IRunning { 
     public Cat(String name) { 
         super(name); 
     } 
     @Override 
     public void run() { 
         System.out.println(this.name + "正在用四條腿跑"); 
     } 
}

魚 , 是會游的。

class Fish extends Animal implements ISwimming { 
     public Fish(String name) { 
         super(name); 
     } 
     @Override 
     public void swim() { 
         System.out.println(this.name + "正在用尾巴游泳"); 
     } 
}

青蛙 , 既能跑 , 又能游 ( 兩棲動物 )。

class Frog extends Animal implements IRunning, ISwimming { 
     public Frog(String name) { 
         super(name); 
     } 
     @Override 
     public void run() { 
         System.out.println(this.name + "正在往前跳"); 
     } 
     @Override 
     public void swim() { 
         System.out.println(this.name + "正在蹬腿游泳"); 
     } 
}

還有一種神奇的動物 , 水陸空三棲 , 叫做 " 鴨子 "。

class Duck extends Animal implements IRunning, ISwimming, IFlying {
    public Duck(String name) {
        super(name);
    }
    @Override
    public void fly() {
        System.out.println(this.name + "正在用翅膀飛");
    }
    @Override
    public void run() {
        System.out.println(this.name + "正在用兩條腿跑");
    }
    @Override
    public void swim() {
        System.out.println(this.name + "正在漂在水上");
    }
}

上面的代碼展示了 Java 面向?qū)ο缶幊讨凶畛R姷挠梅? 一個類繼承一個父類, 同時實現(xiàn)多種接口.
繼承表達(dá)的含義是 is - a 語義, 而接口表達(dá)的含義是 具有 xxx 特性 .
貓是一種動物, 具有會跑的特性.
青蛙也是一種動物, 既能跑, 也能游泳
鴨子也是一種動物, 既能跑, 也能游, 還能飛

接口間的繼承

接口可以繼承一個接口, 達(dá)到復(fù)用的效果. 使用 extends 關(guān)鍵字.

interface IRunning {
    void run();
}
interface ISwimming {
    void swim();
}
// 兩棲的動物, 既能跑, 也能游
interface IAmphibious extends IRunning, ISwimming {
}
class Frog implements IAmphibious { 
 ...
}

通過接口繼承創(chuàng)建一個新的接口 IAmphibious 表示 " 兩棲的 ". 此時實現(xiàn)接口創(chuàng)建的 Frog 類 , 就繼續(xù)要實現(xiàn) run 方法 , 也需要實現(xiàn) swim 方法 . 接口使用實例 給對象數(shù)組排序

class Student{
    private String name;
    private int score;
    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }
    @Override
    public String toString() {
        return "[" + this.name + ":" + this.score + "]";
    }
}
public class test {
    public static void main(String[] args) {
        Student[] students = new Student[] {
                new Student("張三", 95),
                new Student("李四", 96),
                new Student("王五", 97),
                new Student("趙六", 92),
        };
        Arrays.sort(students);
        System.out.println(Arrays.toString(students));
    }
}

運行會發(fā)現(xiàn),拋異常了,原因是我們是對學(xué)生對象進行排序的,而非像整數(shù)這樣顯而易見能比大小的,因此我們需要實現(xiàn)Comparable接口,并實現(xiàn)其compareTo()方法。

 (法一)實現(xiàn)Comparable接口的compareTo()方法

class Student implements Comparable<Student>{
    private String name;
    private int score;
    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }
    @Override
    public String toString() {
        return "[" + this.name + ":" + this.score + "]";
    }
//    @Override
//    public int compareTo(Object o) {
//        Student s=(Student)o;
//        return this.score-s.score;
//    }
    @Override
    public int compareTo(Student o) {
        return this.score-o.score;
    }
}
public class test {
    public static void main(String[] args) {
        Student[] students = new Student[] {
                new Student("張三", 95),
                new Student("李四", 96),
                new Student("王五", 97),
                new Student("趙六", 92),
        };
        Arrays.sort(students);
        System.out.println(Arrays.toString(students));
    }
}

 運行結(jié)果

(法二)實現(xiàn)Comparator比較器的compare()方法

class Student{
    public String name;
    public int score;
    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }
    @Override
    public String toString() {
        return "[" + this.name + ":" + this.score + "]";
    }
}
class AgeComparator implements Comparator<Student>{
    @Override
    public int compare(Student o1, Student o2) {
        return o1.score-o2.score;
    }
}
class NameComparator implements Comparator<Student>{
    @Override
    public int compare(Student o1, Student o2) {
        return o1.name.compareTo(o2.name);
    }
}
public class test {
    public static void main(String[] args) {
        Student student1 = new Student("zhangsan",10);
        Student student2 = new Student("lisi",15);
        AgeComparator ageComparator = new AgeComparator();
        System.out.println(ageComparator.compare(student1, student2));
        NameComparator nameComparator = new NameComparator();
        System.out.println(nameComparator.compare(student1,student2));
    }
}

運行結(jié)果

Clonable接口和深拷貝

Java 中內(nèi)置了一些很有用的接口, Clonable 就是其中之一.
Object 類中存在一個 clone 方法, 調(diào)用這個方法可以創(chuàng)建一個對象的 "拷貝". 但是要想合法調(diào)用 clone 方法, 必須要先實現(xiàn) Clonable 接口, 否則就會拋出 CloneNotSupportedException 異常.

class Money{
    public double money = 19.9;
}
class Person implements Cloneable{
    public int age;
    public Money m;
    public Person(int age) {
        this.age = age;
        this.m = new Money();
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
    @Override
    public String toString() {
        return "Person{" +
                " age=" + age +
                '}';
    }
}
public class Test2 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person(10);
        Person person2 = (Person)person1.clone();
        System.out.println(person1.m.money);
        System.out.println(person2.m.money);
        System.out.println("==========================");
        person2.m.money = 99.99;
        System.out.println(person1.m.money);
        System.out.println(person2.m.money);
    }
}

運行結(jié)果

與我們預(yù)期的19.9    99.99不符,顯然是因為這里是淺拷貝,因此我們需要對m實現(xiàn)深拷貝。

原因如下圖:

實現(xiàn)深拷貝后

class Money implements Cloneable{
    public double money = 19.9;
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
class Person implements Cloneable{
    public int age;
    public Money m;
    public Person(int age) {
        this.age = age;
        this.m = new Money();
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person tmp = (Person) super.clone();
        tmp.m = (Money) this.m.clone();
        return tmp;
    }
    @Override
    public String toString() {
        return "Person{" +
                " age=" + age +
                '}';
    }
}
public class Test2 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person(10);
        Person person2 = (Person)person1.clone();
        System.out.println(person1.m.money);
        System.out.println(person2.m.money);
        System.out.println("==========================");
        person2.m.money = 99.99;
        System.out.println(person1.m.money);
        System.out.println(person2.m.money);
    }
}

運行結(jié)果:

實現(xiàn)方法如下圖:

抽象類和接口的區(qū)別

核心區(qū)別: 抽象類中可以包含普通方法和普通字段, 這樣的普通方法和字段可以被子類直接使用(不必重寫), 而接口中不能包含普通方法, 子類必須重寫所有的抽象方法.

到此這篇關(guān)于Java中的包、抽象類、接口詳解的文章就介紹到這了,更多相關(guān)Java包 抽象類 接口內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論