一文搞懂Java類(lèi)和對(duì)象

簡(jiǎn)介

Java類(lèi)是Java編程語(yǔ)言的基本構(gòu)建塊。Java類(lèi)是用于創(chuàng)建對(duì)象以及定義數(shù)據(jù)類(lèi)型和方法的模板。Java類(lèi)對(duì)象應(yīng)該具有基本的類(lèi)屬性。本文將通過(guò)代碼示例解釋Java類(lèi)的工作原理。

什么是Java類(lèi)?

Java類(lèi)是面向?qū)ο缶幊陶Z(yǔ)言的基本概念。Java類(lèi)是用戶(hù)定義的模板或藍(lán)圖,其中定義了對(duì)象、數(shù)據(jù)成員和方法,以及構(gòu)建特定對(duì)象類(lèi)型的一組指令。同一Java類(lèi)的變量和方法對(duì)于所有類(lèi)對(duì)象都是通用的。

在Java中,class關(guān)鍵字用于定義Java類(lèi)。

如何定義Java類(lèi)?

語(yǔ)法:

class <class-name>
{
    [data members]
    [method];
}

代碼示例:

class MyClass {
    int x = 5;         //數(shù)據(jù)成員
    void fun() {
        System.out.println("This is method");
    }
}

Java類(lèi)的三個(gè)主要組成部分是什么?

1) Java中的類(lèi)變量是什么?

變量是用于存儲(chǔ)值的保留內(nèi)存位置。換句話說(shuō),當(dāng)我們想要存儲(chǔ)任何值并給它命名時(shí),該值在內(nèi)存中占據(jù)了一個(gè)保留空間,這稱(chēng)為變量。

變量具有任何位于內(nèi)存中的值。

語(yǔ)法:

<access specifier> <data type> <variable name> = <value>;

如何聲明變量?

代碼示例:

int x;     (int 是數(shù)據(jù)類(lèi)型,x 是變量名)
int y;
int x , y;
int x = 4 , y = 5;
byte p = 65;
double pi = 3.1415;
char q = 's';

Java中不同類(lèi)型的變量是什么?

1. Java中的局部變量

在方法、構(gòu)造函數(shù)和塊中聲明的變量稱(chēng)為局部變量。它在方法、構(gòu)造函數(shù)、塊創(chuàng)建后創(chuàng)建,類(lèi)看不到局部變量,也無(wú)法訪問(wèn)它。它的作用范圍有限,因?yàn)樗鼉H在方法內(nèi)部使用。

例如,我們首先創(chuàng)建一個(gè)類(lèi)和一個(gè)方法,然后在方法內(nèi)部聲明兩個(gè)局部變量。

public class LocalVariableExm {
    void message() {     //這是一個(gè)方法
        int p;                     //局部變量的聲明
        int x = 10;      //局部變量的聲明與初始化
    }
}

Java中的靜態(tài)變量

靜態(tài)變量是一種非常重要的變量類(lèi)型。我們使用 static 關(guān)鍵字與變量一起使用,因此稱(chēng)為靜態(tài)變量。靜態(tài)變量在類(lèi)內(nèi)部、方法、構(gòu)造函數(shù)和塊外部聲明。靜態(tài)變量屬于類(lèi)而不是對(duì)象,存儲(chǔ)在靜態(tài)內(nèi)存中。其默認(rèn)值為0,我們可以通過(guò)類(lèi)名調(diào)用靜態(tài)變量,因此無(wú)需為靜態(tài)變量創(chuàng)建對(duì)象。

例如,首先我們創(chuàng)建一個(gè)類(lèi),并在方法外部聲明了三個(gè)變量,其中兩個(gè)是靜態(tài)變量。

public class StaticVariableExm {
    int p;
    static int q = 10;     // 靜態(tài)變量并初始化
    static int r;          // 靜態(tài)變量聲明
    void message() {
    }
}

Java中的實(shí)例變量

實(shí)例變量在類(lèi)中聲明,但在方法、構(gòu)造函數(shù)或塊外部。它的作用范圍最廣,因?yàn)樗陬?lèi)中全局可見(jiàn)。當(dāng)對(duì)象創(chuàng)建時(shí),實(shí)例變量也被創(chuàng)建。在實(shí)例變量被創(chuàng)建時(shí),它在堆內(nèi)存中占據(jù)空間,并通過(guò)對(duì)象調(diào)用,默認(rèn)值為0。

例如,首先我們創(chuàng)建一個(gè)類(lèi),并在方法外部聲明了兩個(gè)實(shí)例變量。

public class InstanceVariableExm {
    int a;      // 實(shí)例變量的聲明
    int b = 10;  // 實(shí)例變量的聲明與初始化
    void message() {
    }
}

2) 什么是Java中的構(gòu)造函數(shù)?

構(gòu)造函數(shù)就像Java中的一個(gè)特殊方法,用于初始化Java類(lèi)的對(duì)象。構(gòu)造函數(shù)對(duì)于每個(gè)Java類(lèi)都非常重要。如果我們不聲明構(gòu)造函數(shù),編譯器會(huì)創(chuàng)建一個(gè)Java類(lèi)的默認(rèn)構(gòu)造函數(shù)。

構(gòu)造函數(shù)必須與Java類(lèi)同名。它沒(méi)有返回類(lèi)型。

Java中的不同類(lèi)型的構(gòu)造函數(shù)是什么?

默認(rèn)構(gòu)造函數(shù)

默認(rèn)構(gòu)造函數(shù)沒(méi)有參數(shù),如果我們不聲明構(gòu)造函數(shù),編譯器會(huì)自動(dòng)創(chuàng)建該Java類(lèi)的默認(rèn)構(gòu)造函數(shù)。

語(yǔ)法:

<class-name>() {}

以下程序創(chuàng)建了一個(gè)默認(rèn)構(gòu)造函數(shù)并輸出消息。完整程序如下:

public class DefaultConstructor {
    DefaultConstructor() {
        System.out.println("This is default constructor example");
    }
    public static void main(String args[]) {
        DefaultConstructor d = new DefaultConstructor();
    }
}

什么是 Java 類(lèi)中的數(shù)據(jù)成員?

數(shù)據(jù)成員是在每次創(chuàng)建對(duì)象時(shí)分配內(nèi)存空間的那些成員。數(shù)據(jù)成員通常用于存儲(chǔ)特定的值。

語(yǔ)法

數(shù)據(jù)類(lèi)型 v1,v2,v3,……vn;


class DataMember
{
   int v1,v2,v3;
   float f1,f2;
}

什么是 Java 類(lèi)中的訪問(wèn)修飾符?

訪問(wèn)修飾符用于確定 Java 類(lèi)、數(shù)據(jù)成員、方法或構(gòu)造函數(shù)的可訪問(wèn)性(作用域)。通過(guò)訪問(wèn)修飾符,我們可以設(shè)置 Java 類(lèi)、變量和方法的訪問(wèn)級(jí)別。

有哪些不同類(lèi)型的訪問(wèn)修飾符?

Java 中有四種訪問(wèn)修飾符:

  • public
  • private
  • protected
  • default(默認(rèn))

下表列出了訪問(wèn)修飾符:

訪問(wèn)修飾符關(guān)鍵詞
公共訪問(wèn)修飾符public
私有訪問(wèn)修飾符private
受保護(hù)訪問(wèn)修飾符protected
默認(rèn)訪問(wèn)修飾符無(wú)關(guān)鍵詞

1) 公共訪問(wèn)修飾符

公共訪問(wèn)修飾符在所有地方都可以訪問(wèn)。它具有所有修飾符中最廣泛的作用域。在公共類(lèi)中聲明的變量、方法和構(gòu)造函數(shù)對(duì) Java 程序中的任何類(lèi)都是可見(jiàn)的,無(wú)論這些類(lèi)是在同一個(gè)包中還是在不同包中。

完整程序如下所示:

步驟 1. 首先,我們創(chuàng)建一個(gè) Java 類(lèi) PublicExample,其中我們聲明方法 show():


public class PublicExample {
    public void show() {
        System.out.println("Public access modifier example");
    }
}

步驟 2. 接著,我們創(chuàng)建一個(gè)名為 PublicAccess 的類(lèi),在其中調(diào)用 PublicExample 類(lèi)的方法:


public class PublicAccess {
    public static void main(String args[]) {
        PublicExample obj = new PublicExample();
        obj.show();
    }
}

2) 私有訪問(wèn)修飾符

私有訪問(wèn)修飾符只能在類(lèi)內(nèi)訪問(wèn),不能在類(lèi)外訪問(wèn)。聲明為私有的數(shù)據(jù)成員、方法或構(gòu)造函數(shù)受到嚴(yán)格控制。私有訪問(wèn)修飾符不能在類(lèi)外部訪問(wèn)。

除了嵌套類(lèi)外,Java 類(lèi)不能被聲明為私有。

完整程序如下所示:

步驟 1. 首先,我們創(chuàng)建一個(gè) Java 類(lèi) PrivateExample,在其中聲明私有方法 run():


public class PrivateExample{
    private void run() {
        System.out.println("Scooter is running");
    }
}

步驟 2. 接著,我們創(chuàng)建一個(gè) PrivateAccess 類(lèi),在其中調(diào)用 PrivateExample 類(lèi)的方法:


public class PrivateAccess{
    public static void main(String args[]) {
        PrivateExample s = new PrivateExample();
        s.run();  // 編譯時(shí)錯(cuò)誤
    }
}

注意: 在這個(gè)例子中,我們創(chuàng)建了兩個(gè) Java 類(lèi) PrivateExample 和 PrivateAccess。PrivateExample 包含私有方法 run()。如果我們嘗試在類(lèi)外部訪問(wèn)私有方法,將會(huì)產(chǎn)生編譯時(shí)錯(cuò)誤。

3) 受保護(hù)的訪問(wèn)修飾符

受保護(hù)的訪問(wèn)修飾符可在包內(nèi)和包外通過(guò)繼承訪問(wèn)。

受保護(hù)的訪問(wèn)修飾符可以應(yīng)用于變量、方法和構(gòu)造函數(shù),但不能應(yīng)用于 Java 類(lèi)。父類(lèi)中的變量、方法和構(gòu)造函數(shù)被聲明為受保護(hù),可以在其他包中的子類(lèi)中訪問(wèn)。

完整程序如下所示:

步驟 1. 首先,我們?cè)?pack1 包中創(chuàng)建一個(gè)公有的 Java 類(lèi) ProtectedExample,其中聲明一個(gè)受保護(hù)的方法 display():


package pack1;
public class ProtectedExample{
    protected void display() {
        System.out.println("Protected access modifier example");
    }
}

步驟 2. 接著,我們?cè)?pack2 包中創(chuàng)建一個(gè)公有的 Java 類(lèi) ProtectedAccess,并調(diào)用 ProtectedExample 類(lèi)的方法:


package pack2;
import pack1.*;
public class ProtectedAccess extends ProtectedExample{
    public static void main(String args[]) {
        ProtectedAccess p = new ProtectedAccess();
        p.display();
    }
}

4) 默認(rèn)訪問(wèn)修飾符

當(dāng)我們不使用任何修飾符時(shí),它被視為 Java 中的默認(rèn)訪問(wèn)修飾符。默認(rèn)訪問(wèn)修飾符僅在包內(nèi)可訪問(wèn)。

任何 Java 類(lèi)、變量、方法和構(gòu)造函數(shù)的默認(rèn)訪問(wèn)修飾符,僅在同一包中的類(lèi)可以訪問(wèn)。默認(rèn)訪問(wèn)修飾符不用于接口中的變量和方法。

完整程序如下所示。

package pack1;
 class DefaultExample {
    void msg() {
        System.out.println("默認(rèn)訪問(wèn)修飾符示例");
    }
}

步驟 1:首先,我們?cè)诎?pack1 中創(chuàng)建一個(gè)名為 DefaultExample 的默認(rèn) Java 類(lèi),并聲明一個(gè)方法 msg()

步驟 2:其次,我們?cè)诎?pack2 中創(chuàng)建一個(gè)名為 DefaultAccess 的默認(rèn) Java 類(lèi),其中調(diào)用 DefaultClass 類(lèi)的方法:

package pack2;
import pack1.*;
 class DefaultAccess{
        public static void main(String args[]) {
            DefaultClass d = new DefaultClass(); // 編譯時(shí)錯(cuò)誤
            r.msg(); // 編譯時(shí)錯(cuò)誤
        }
}

注意:在這個(gè)示例中,我們創(chuàng)建了兩個(gè) Java 類(lèi) DefaultClassDefaultAccess。 DefaultClass 是一個(gè)默認(rèn)的 Java 類(lèi),無(wú)法在包外訪問(wèn)。因此,它會(huì)產(chǎn)生編譯時(shí)錯(cuò)誤。

Java 中有多少種類(lèi)型的類(lèi)?

Java 中有三種主要類(lèi)型的類(lèi):

  • 抽象 Java 類(lèi)
  • 嵌套 Java 類(lèi)
  • 最終 Java 類(lèi)
  • 單例 Java 類(lèi)

1) 什么是 Java 中的抽象類(lèi)?

在了解抽象 Java 類(lèi)之前,我們應(yīng)該了解 Java 中的抽象。

抽象

在 Java 中,抽象是一種向用戶(hù)隱藏實(shí)現(xiàn)細(xì)節(jié)的過(guò)程,并僅向用戶(hù)提供功能。例如,當(dāng)我們想在計(jì)算器中計(jì)算一些數(shù)據(jù)時(shí),我們使用其按鍵,但不知道它是如何在內(nèi)部工作的。

因此,當(dāng)我們?cè)谌魏晤?lèi)中使用抽象關(guān)鍵字時(shí),該類(lèi)稱(chēng)為抽象 Java 類(lèi)。它僅向用戶(hù)提供必要的內(nèi)容,并隱藏內(nèi)部過(guò)程。

抽象 Java 類(lèi)可以有抽象方法和非抽象方法。如果一個(gè)類(lèi)有一個(gè)抽象方法,則該類(lèi)必須是抽象 Java 類(lèi)。如果我們想使用抽象類(lèi),它必須被擴(kuò)展并實(shí)現(xiàn)其方法。如果我們擴(kuò)展一個(gè)抽象 Java 類(lèi),我們必須為其中的所有抽象方法提供實(shí)現(xiàn)。

完整程序如下所示。

abstract class AbstractClass {
    abstract void work();
}

步驟 1:首先,我們創(chuàng)建一個(gè)名為 Employee 的抽象 Java 類(lèi),其中聲明一個(gè)名為 work() 的抽象方法。

步驟 2:其次,我們創(chuàng)建一個(gè)名為 WomanEmployee 的公共 Java 類(lèi),在其中訪問(wèn)方法 work(),其實(shí)現(xiàn)由 WomanEmployee 類(lèi)給出。

public class AbstractClass2 extends AbstractClass{
    void work() {
            System.out.println("抽象類(lèi)示例");
        }
        public static void main(String args[]) {
            AbstractClass p = new AbstractClass2();
            p.work();
        }
}

2) 什么是嵌套 Java 類(lèi)?

Java 編程語(yǔ)言允許您在一個(gè)類(lèi)內(nèi)定義另一個(gè)類(lèi)。我們使用嵌套類(lèi)來(lái)將類(lèi)和接口在一個(gè)地方進(jìn)行邏輯分組。這可以提高可讀性和可維護(hù)性,并且可以訪問(wèn)外部類(lèi)的所有成員(公共、私有、受保護(hù))。

語(yǔ)法

class OuterClass{
    ......
    class InnerClass{
        // 嵌套 Java 類(lèi)
    }
}

嵌套類(lèi)在 Java 中的優(yōu)點(diǎn)

  1. 嵌套 Java 類(lèi)顯示一種特殊類(lèi)型的關(guān)系;它可以訪問(wèn)外部類(lèi)的所有成員,包括私有成員。
  2. 嵌套 Java 類(lèi)主要用于使我們的程序更具可讀性和可維護(hù)性,因?yàn)樗鼘㈩?lèi)和接口在一個(gè)地方進(jìn)行邏輯分組。
  3. 嵌套類(lèi)需要寫(xiě)的代碼更少。

嵌套類(lèi)的類(lèi)型

  1. 非靜態(tài)嵌套類(lèi)
  2. 靜態(tài)嵌套類(lèi)

非靜態(tài)嵌套類(lèi)在 Java 中也稱(chēng)為內(nèi)部類(lèi)。

Java 中的成員內(nèi)部類(lèi)

成員內(nèi)部類(lèi)是在類(lèi)內(nèi)部但在方法外部創(chuàng)建的。它是一個(gè)非靜態(tài)內(nèi)部類(lèi)。在 Java 中創(chuàng)建內(nèi)部成員類(lèi)很簡(jiǎn)單。我們只需在類(lèi)內(nèi)編寫(xiě)一個(gè)類(lèi)。內(nèi)部類(lèi)可以是私有的,一旦我們將內(nèi)部類(lèi)聲明為私有,就無(wú)法從外部類(lèi)的對(duì)象訪問(wèn)它。

語(yǔ)法

class Outer{
    class Inner {
        // 成員內(nèi)部類(lèi)
    }
}

完整程序如下所示。

public class MemberClassExample {
    private int data = 30;
    class MemberClassInner {
        void msg() {
            System.out.println("data is " + data);
        }
    }
    public static void main(String args[]) {
        MemberClassExample obj = new MemberClassExample();
        MemberClassExample.MemberClassInner in = obj.new MemberClassInner();
        in.msg();
    }
}

注意:在示例中,我們?cè)趦?nèi)部成員類(lèi)中創(chuàng)建了一個(gè) display() 方法,它訪問(wèn)外部類(lèi)的私有數(shù)據(jù)成員。

Java 中的匿名內(nèi)部類(lèi)

沒(méi)有名稱(chēng)的類(lèi)稱(chēng)為 Java 中的匿名內(nèi)部類(lèi)。它必須在我們需要覆蓋類(lèi)和接口的方法時(shí)使用。

我們可以同時(shí)聲明和初始化它們。完整程序如下所示。

public class AnonoymousClassExample {
    public static void main(String[] args) {
        AnonoymousDemo a = new AnonoymousDemo() {
            public void message() {
                System.out.println("匿名內(nèi)部類(lèi)示例");
            }
        }; // 匿名類(lèi)體在此關(guān)閉
        // a 包含匿名子類(lèi) AnonoymousClassExample 的對(duì)象。
        a.message();
    }
}
class AnonoymousDemo {
    public void message() {
        System.out.println("消息");
    }
}

Java 中的局部?jī)?nèi)部類(lèi)

在方法內(nèi)部創(chuàng)建的 Java 類(lèi)稱(chēng)為局部?jī)?nèi)部類(lèi) Java;如果我們想調(diào)用局部?jī)?nèi)部類(lèi)的方法,那么我們必須在方法內(nèi)部初始化這個(gè)類(lèi)。

完整程序如下所示。

public class LocalInnerClassExample {
    private int data = 30;
    void display() {
        class Local {
            void msg() {
                System.out.println(data);
            }
        }
        Local l = new Local();
        l.msg();
    }
    public static void main(String args[]) {
        LocalInnerClassExample obj = new LocalInnerClassExample();
        obj.display();
    }
}

Java 中的靜態(tài)嵌套類(lèi)

靜態(tài)類(lèi)不能訪問(wèn)非靜態(tài)數(shù)據(jù)成員和方法。它可以訪問(wèn)外部類(lèi)的靜態(tài)成員,無(wú)論是私有、公共還是受保護(hù)的,并且只能通過(guò)外部類(lèi)名稱(chēng)訪問(wèn)。當(dāng)在另一個(gè) Java 類(lèi)內(nèi)部創(chuàng)建靜態(tài)類(lèi)時(shí),它稱(chēng)為靜態(tài)嵌套類(lèi)。

語(yǔ)法

class Outer{
    static NestedClass {
        // 靜態(tài)嵌套類(lèi)
    }
}

完整程序如下所示。

public class StaticNestedClassExample {
    static int age = 30;
    static class StaticClassAccess {
        void display() {
            System.out.println("員工年齡是 " + age);
        }
    }
    public static void main(String args[]) {
        StaticNestedClassExample.StaticClassAccess obj = new StaticNestedClassExample.StaticClassAccess();
        obj.display();
    }
}

3) 什么是最終類(lèi)?

最終類(lèi)在 Java 中是一個(gè)不可更改的類(lèi)。它不能被擴(kuò)展,也不能作為基類(lèi)。使用最終類(lèi)的主要目的是為了不讓其他類(lèi)繼承它。

當(dāng)我們不希望其他類(lèi)繼承時(shí),我們將類(lèi)聲明為最終類(lèi);這是定義常量的好方法。完整程序如下所示。

final class FinalClassExample {
    void display() {
        System.out.println("最終類(lèi)示例");
    }
}
// 編譯時(shí)錯(cuò)誤
class NewClass extends FinalClassExample { } // 無(wú)法擴(kuò)展最終類(lèi)

上面的代碼會(huì)導(dǎo)致編譯時(shí)錯(cuò)誤,表示無(wú)法擴(kuò)展最終類(lèi)。

4) 什么是單例類(lèi)?

單例類(lèi)是設(shè)計(jì)模式中的一種模式,它確保一個(gè)類(lèi)僅有一個(gè)實(shí)例,并提供全局訪問(wèn)。它主要用于控制對(duì)共享資源的訪問(wèn)。

完整程序如下所示。

class Singleton {
    private static Singleton instance = new Singleton(); // 唯一實(shí)例
    private Singleton() { } // 私有構(gòu)造函數(shù)
    public static Singleton getInstance() {
        return instance;
    }
    public void display() {
        System.out.println("單例類(lèi)示例");
    }
}
public class SingletonExample {
    public static void main(String args[]) {
        Singleton s = Singleton.getInstance();
        s.display();
    }
}

3) 最終 Java 類(lèi)

當(dāng)我們?cè)谌魏晤?lèi)前使用 final 時(shí),它被稱(chēng)為最終 Java 類(lèi)。最終類(lèi)不能被繼承。如果任何類(lèi)被聲明為最終的,那么它的所有方法也隱式地被聲明為最終的。

語(yǔ)法

final class <類(lèi)名> {
    // 代碼
}

完整程序如下:


final class FinalClassExample {
}
class Manager extends FinalClassExample {  // 編譯時(shí)錯(cuò)誤
    void work() {
        System.out.println("努力工作");
    }
    public static void main(String args[]) {
        Manager m1 = new Manager();
        m1.work();
    }
}

注意

在這個(gè)例子中,我們創(chuàng)建了一個(gè)名為 FinalClassExample 的最終 Java 類(lèi)和另一個(gè)名為 Manager 的 Java 類(lèi)。我們嘗試?yán)^承這個(gè)最終類(lèi),但程序在編譯時(shí)出現(xiàn)錯(cuò)誤。

4) 單例 Java 類(lèi)

在面向?qū)ο缶幊讨?,單例?lèi)是指在任何時(shí)候只能有一個(gè)對(duì)象的類(lèi)。單例通??刂茖?duì)資源的訪問(wèn),例如數(shù)據(jù)庫(kù)連接或套接字。其目的是創(chuàng)建一個(gè)對(duì)象的單一實(shí)例,這些對(duì)象在運(yùn)行時(shí)創(chuàng)建成本高昂,并盡量重用同一個(gè)對(duì)象。這些對(duì)象主要是不可變的。

實(shí)現(xiàn)單例類(lèi)需要遵循一些基本規(guī)則。

  1. 構(gòu)造函數(shù)應(yīng)該是私有的。
  2. 聲明一個(gè)該類(lèi)的靜態(tài)變量對(duì)象。
  3. 聲明一個(gè)靜態(tài)方法以返回實(shí)例。

完整程序如下。

步驟 1

首先,我們創(chuàng)建一個(gè)名為 SingletonClassExample 的單例類(lèi)。


public class SingletonClassExample {
    private static SingletonClassExample singleton = new SingletonClassExample();
    public static SingletonClassExample getInstance() {
        return singleton;
    }
    protected static void demoMethod() {
        System.out.println("單例的 demoMethod");
    }
}

步驟 2

其次,我們創(chuàng)建一個(gè)名為 SingletonDemo 的公共類(lèi)以訪問(wèn)單例類(lèi)。


public class SingletonDemo {
    public static void main(String[] args) {
        SingletonClassExample tmp = SingletonClassExample.getInstance();
        tmp.demoMethod();
    }
}

總結(jié)

在本教程中,我們學(xué)習(xí)了各種 Java 類(lèi)以及如何在 Java 程序中使用它們。

 

若你想提升Java技能,可關(guān)注我們的Java培訓(xùn)課程。