📜  Java中的类和对象

📅  最后修改于: 2020-03-18 14:07:34             🧑  作者: Mango

类和对象是面向对象编程的基本概念,它围绕着现实生活中的实体。

类是用户定义的蓝图或原型,从中可以创建对象。它表示一种类型的所有对象共有的一组属性或方法。通常,类声明可以按顺序包括以下组件:

  1. 修饰符  :一个类可以是公共的,也可以具有默认访问权限
  2. 类名:  名称应以首字母开头(按惯例大写)。
  3. 超类(如果有):类的父类(超类)的名称(如果有的话),以关键字extends开头。一个类只能extends一个父类。
  4. 接口(如果有):由类实现的接口的逗号分隔列表(如果有的话),其后为关键字Implements。一个类可以实现多个接口。
  5. 正文由括号{}包围的类正文。

构造函数用于初始化新对象。字段是提供类及其对象状态的变量,而方法则用于实现类及其对象的行为。
真实的应用程序中使用了各种类型的类,例如  嵌套类,匿名类,lambda表达式。

对象

它是面向对象编程的基本单元,代表现实生活中的实体。典型的Java程序会创建许多对象,您知道这些对象通过调用方法进行交互。一个对象包括:

  1. 状态:它由对象的属性表示,它还反映了对象的属性。
  2. 行为:它由对象的方法表示,它还反映了一个对象对其他对象的响应。
  3. 身份:它为一个对象赋予唯一的名称,并使一个对象能够与其他对象进行交互。

对象的示例:狗(Dog)

对象对应于现实世界中发现的事物。例如,图形程序可以具有诸如“圆形”,“正方形”,“菜单”之类的对象。在线购物系统可能具有“购物车”,“客户”和“产品”之类的对象。

声明对象(也称为实例化类)
创建类的对象时,该类被称为实例化。所有实例都共享类的属性和行为。但是这些属性的值(即状态)对于每个对象都是唯一的。单个类可以具有任意数量的实例。
范例:

当我们声明类似(type name;)的变量时。这通知编译器我们将使用name来引用类型为type的数据。对于原始变量,此声明还为该变量保留适当的内存量。因此,对于引用变量,类型必须严格是具体的类名称。通常,我们不能创建抽象类或接口的对象。

Dog tuffy;

如果我们这样声明引用变量(tuffy),则其值将不确定(null),直到实际创建并分配一个对象为止。此时仅声明引用变量不会创建对象。

初始化对象

new运算符通过为新对象分配内存并返回对该内存的引用来实例化一个类。new运算符还调用类构造函数。

// Class声明
public class Dog
{
    // 实例变量
    String name;
    String breed;
    int age;
    String color;
    // 构造器
    public Dog(String name, String breed,
                   int age, String color)
    {
        this.name = name;
        this.breed = breed;
        this.age = age;
        this.color = color;
    }
    // 方法1
    public String getName()
    {
        return name;
    }
    // 方法2
    public String getBreed()
    {
        return breed;
    }
    // 方法3
    public int getAge()
    {
        return age;
    }
    // 方法4
    public String getColor()
    {
        return color;
    }
    @Override
    public String toString()
    {
        return("我的名字是 "+ this.getName()+
               ".\n我的品种,年龄和颜色: " +
               this.getBreed()+"," + this.getAge()+
               ","+ this.getColor());
    }
    public static void main(String[] args)
    {
        Dog tuffy = new Dog("tuffy","papillon", 5, "white");
        System.out.println(tuffy.toString());
    }
}

输出:

我的名字是 tuffy.
我的品种,年龄和颜色: papillon,5,white

此类包含一个构造函数。我们可以识别出构造函数,因为其声明使用与类相同的名称,并且没有返回类型。Java编译器根据参数的数量和类型来区分构造函数。Dog类中的构造函数采用四个参数。以下语句提供“ tuffy”,“ papillon”,5,“ white”作为这些参数的值:

Dog tuffy = new Dog("tuffy","papillon",5, "white");
  • 执行此语句的结果可以说明:

注意:所有类都有至少一个构造函数。如果一个声明变量的时候,没有显式声明任何类,则Java编译器会自动提供一个无参数的构造函数,也称为默认构造函数。此默认构造函数调用类父级的无参数构造函数(因为它仅包含一个语句,即super();),如果该类没有其他父级,则调用Object类的构造函数(因为Object类是所有类的直接或间接父类) )。

创建类对象的方法

在Java中有四种创建对象的方法。严格来说,只有一种方法(使用new关键字),即使用new关键字。

  • 使用new关键字:这是在Java中创建对象的最常见和通用的方法。例:
    // 创建Test的对象
    Test t = new Test();
  • 使用Class.forName(String className)方法 :java.lang包中有一个预定义的类,Class.forName(String className)方法使用给定的字符串名称返回与该类关联的Class对象。我们必须提供一个类的完全限定名称。在对此Class对象调用new Instance()方法时,将使用给定的字符串名称返回该类的新实例。
    // 使用Class.forName创建的实例
    Test obj = (Test)Class.forName("com.p1.Test").newInstance();
  • 使用clone()方法:Object类中存在clone()方法,它创建并返回对象的副本。
    // 创建Test的对象
    Test t1 = new Test();
    // 创建一个上述对象的clone
    Test t2 = (Test)t1.clone();
  • 反序列化序列化是从文件中的保存状态读取对象的技术。
    FileInputStream file = new FileInputStream(filename);
    ObjectInputStream in = new ObjectInputStream(file);
    Object obj = in.readObject();

在一个类下创建多个对象(一种好的做法)

  • 实际中,我们需要使用同一个类下的不同对象。创建多个引用来存储它们不是一个好习惯,因此我们声明一个静态引用变量,并在需要时使用它。在这种情况下,内存浪费较少。Java 的垃圾收集器将销毁不再引用的对象。例:
    Test test = new Test();
    test = new Test();
  • 在继承系统中,我们使用父类引用变量来存储子类对象。在这种情况下,我们可以使用相同的引用变量切换到不同的子类对象。例:
    class Animal {}
    class Dog extends Animal {}
    class Cat extends Animal {}
    public class Test
    {
        // 创建Dog实例
        Animal obj = new Dog();
        // 创建Cat 实例
        obj = new Cat();
    }

匿名对象
 匿名对象是已实例化但未存储在引用变量中的对象。

  • 它们用于立即的方法调用。
  • 它们将在方法调用后销毁。
  • 它们被广泛用于不同的库中。例如,在AWT库中,它们用于对捕获事件执行某些操作(例如,按键)。
  • 在下面的示例中,当按下一个按钮(由btn指代)时,我们只是在创建EventHandler类的匿名对象以仅调用handle方法。
    btn.setOnAction(new EventHandler()
    {
        public void handle(ActionEvent event)
        {
            System.out.println("Hello World!");
        }
    });