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

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

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

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

導(dǎo)入包

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

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

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

注意事項(xiàng) : import 和 C++ 的 #include 差別很大 . C++ 必須 #include 來(lái)引入其他文件內(nèi)容 , 但是 Java 不需要 . import 只是為了寫代碼的時(shí)候更方便 . 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)入的方式寫起來(lái)更方便一些. 
        // 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ī)則

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

常見的系統(tǒng)包

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

抽象類

語(yǔ)法規(guī)則

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

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

總結(jié) 

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

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

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

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

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

注意事項(xiàng):

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

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

2) 抽象方法不能是 private 的

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

3) 抽象類中可以包含其他的非抽象方法 , 也可以包含字段 . 這個(gè)非抽象方法和普通方法的規(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)建對(duì)象時(shí),初始化父類的成員變量。

抽象類的作用

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

接口

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

語(yǔ)法規(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 定義一個(gè)接口
2.接口中的方法一定是抽象方法 , 因此可以省略 abstract
3.接口中的方法一定是 public, 因此可以省略 public
4.Cycle 使用 implements 繼承接口 . 此時(shí)表達(dá)的含義不再是 " 擴(kuò)展 ", 而是 " 實(shí)現(xiàn) "
5.在調(diào)用的時(shí)候同樣可以創(chuàng)建一個(gè)接口的引用 , 對(duì)應(yīng)到一個(gè)子類的實(shí)例 .
6.接口不能單獨(dú)被實(shí)例化

接口中只能包含抽象方法. 對(duì)于字段來(lái)說(shuō), 接口中只能包含靜態(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來(lái)定義一個(gè)接口
⒉.接口當(dāng)中的成員變量默認(rèn)是public static final的,一般情況下我們不寫

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

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

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

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

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

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

實(shí)現(xiàn)多個(gè)接口

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

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

另外我們?cè)偬峁┮唤M接口 , 分別表示 " 會(huì)飛的 ", " 會(huì)跑的 ", " 會(huì)游泳的”。

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

接下來(lái)我們創(chuàng)建幾個(gè)具體的動(dòng)物 貓 , 是會(huì)跑的 .

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

魚 , 是會(huì)游的。

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

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

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 + "正在蹬腿游泳"); 
     } 
}

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

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姷挠梅? 一個(gè)類繼承一個(gè)父類, 同時(shí)實(shí)現(xiàn)多種接口.
繼承表達(dá)的含義是 is - a 語(yǔ)義, 而接口表達(dá)的含義是 具有 xxx 特性 .
貓是一種動(dòng)物, 具有會(huì)跑的特性.
青蛙也是一種動(dòng)物, 既能跑, 也能游泳
鴨子也是一種動(dòng)物, 既能跑, 也能游, 還能飛

接口間的繼承

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

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

通過(guò)接口繼承創(chuàng)建一個(gè)新的接口 IAmphibious 表示 " 兩棲的 ". 此時(shí)實(shí)現(xiàn)接口創(chuàng)建的 Frog 類 , 就繼續(xù)要實(shí)現(xiàn) run 方法 , 也需要實(shí)現(xiàn) swim 方法 . 接口使用實(shí)例 給對(duì)象數(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));
    }
}

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

 (法一)實(shí)現(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));
    }
}

 運(yùn)行結(jié)果

(法二)實(shí)現(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));
    }
}

運(yùn)行結(jié)果

Clonable接口和深拷貝

Java 中內(nèi)置了一些很有用的接口, Clonable 就是其中之一.
Object 類中存在一個(gè) clone 方法, 調(diào)用這個(gè)方法可以創(chuàng)建一個(gè)對(duì)象的 "拷貝". 但是要想合法調(diào)用 clone 方法, 必須要先實(shí)現(xiàn) Clonable 接口, 否則就會(huì)拋出 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);
    }
}

運(yùn)行結(jié)果

與我們預(yù)期的19.9    99.99不符,顯然是因?yàn)檫@里是淺拷貝,因此我們需要對(duì)m實(shí)現(xiàn)深拷貝。

原因如下圖:

實(shí)現(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);
    }
}

運(yùn)行結(jié)果:

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

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

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

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

相關(guān)文章

  • 輕松掌握J(rèn)ava享元模式

    輕松掌握J(rèn)ava享元模式

    這篇文章主要幫助大家輕松掌握J(rèn)ava享元模式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • 詳解SpringBoot讀取resource目錄下properties文件的常見方式

    詳解SpringBoot讀取resource目錄下properties文件的常見方式

    這篇文章主要介紹了SpringBoot讀取resource目錄下properties文件的常見方式,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-02-02
  • 用java在web環(huán)境下上傳和下載文件的技巧

    用java在web環(huán)境下上傳和下載文件的技巧

    這篇文章主要介紹了用java在web環(huán)境下上傳和下載文件的技巧的相關(guān)資料
    2016-01-01
  • Spring事務(wù)傳播屬性和隔離級(jí)別詳細(xì)介紹

    Spring事務(wù)傳播屬性和隔離級(jí)別詳細(xì)介紹

    這篇文章主要介紹了Spring事務(wù)傳播屬性和隔離級(jí)別詳細(xì)介紹,同時(shí)涉及傳播行為介紹,超時(shí)設(shè)置等相關(guān)內(nèi)容,需要的朋友可以參考下。
    2017-09-09
  • java并發(fā)編程之深入理解Synchronized的使用

    java并發(fā)編程之深入理解Synchronized的使用

    文詳細(xì)講述了線程、進(jìn)程的關(guān)系及在操作系統(tǒng)中的表現(xiàn),這是多線程學(xué)習(xí)必須了解的基礎(chǔ)。本文將接著講一下Java線程同步中的一個(gè)重要的概念synchronized,希望能夠給你有所幫助
    2021-06-06
  • Spring Boot + Vue 前后端分離開發(fā)之前端網(wǎng)絡(luò)請(qǐng)求封裝與配置

    Spring Boot + Vue 前后端分離開發(fā)之前端網(wǎng)絡(luò)請(qǐng)求封裝與配置

    這篇文章主要介紹了Spring Boot + Vue 前后端分離開發(fā)之前端網(wǎng)絡(luò)請(qǐng)求封裝與配置方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下
    2019-05-05
  • java實(shí)現(xiàn)數(shù)字猜拳小游戲

    java實(shí)現(xiàn)數(shù)字猜拳小游戲

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)數(shù)字猜拳的小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-06-06
  • Spring 日志規(guī)范及作用

    Spring 日志規(guī)范及作用

    日志是在系統(tǒng)運(yùn)行過(guò)程中關(guān)鍵的節(jié)點(diǎn)的數(shù),這個(gè)些日志的記錄方便當(dāng)系統(tǒng)出現(xiàn)問(wèn)題方便問(wèn)題查找,這篇文章主要介紹了Spring 日志規(guī)范及作用,需要的朋友可以參考下
    2024-03-03
  • Java調(diào)用WebService接口的方法

    Java調(diào)用WebService接口的方法

    這篇文章主要介紹了Java調(diào)用WebService接口的方法,實(shí)例分析了有參方法Add的使用技巧,需要的朋友可以參考下
    2015-01-01
  • Spring Data Envers支持有條件變動(dòng)紀(jì)錄的保存和查詢的方法

    Spring Data Envers支持有條件變動(dòng)紀(jì)錄的保存和查詢的方法

    通過(guò)spring-data-envers可以很容易的實(shí)現(xiàn)數(shù)據(jù)變動(dòng)紀(jì)錄的保存和查詢,本文介紹支持有條件變動(dòng)紀(jì)錄的保存和查詢的方法,通過(guò)spring-data-envers很容易的實(shí)現(xiàn)變動(dòng)紀(jì)錄的保存和查詢,只需要增加幾個(gè)注解就可以,感興趣的朋友跟隨小編一起看看吧
    2023-10-10

最新評(píng)論