📜  了解Java中的类和对象

📅  最后修改于: 2020-03-25 01:40:41             🧑  作者: Mango

术语“ 面向对象”解释了将软件组织为结合了数据和行为的不同类型对象的组合概念。因此,面向对象编程(OOP)是一种编程模型,它通过提供一些规则来简化软件开发和维护。程序围绕对象而不是动作和逻辑进行组织。它增加了程序的灵活性和可维护性。由于OOP将数据及其行为(方法)带到单个(对象)位置,因此了解程序的工作变得更加容易。

OOP的基本概念是:

  1. 对象
  2. 封装形式
  3. 继承
  4. 多态
  5. 抽象

本文讨论Java中的对象

面向对象编程中类和对象的要求

类:类是用户定义的蓝图或原型,从中可以创建对象。它表示一种类型的所有对象共有的一组属性或方法。OOP中需要类,因为:

  • 它提供了用于创建对象的模板,该对象可以将代码绑定到数据中。
  • 它具有方法和数据的定义。
  • 它支持面向对象编程的继承属性,因此可以维护类的层次结构。
  • 它有助于维护成员变量的访问规范。

对象:它是面向对象编程的基本单元,它代表现实生活中的实体。
现实中的实体共有两个特征:它们都有属性和行为。
一个对象包括:

  • 状态:由对象的属性表示。
  • 行为:用对象的方法表示。它显示一个对象与其他对象的交互。
  • 身份:为对象赋予唯一名称。它还授予一个对象与其他对象进行交互的权限。

OOP中需要对象,因为可以创建对象来调用非静态函数,该函数不存在于Main方法中,而是存在于Class中,并且还提供了用于存储数据的空间的名称。
示例:要添加两个数字,需要将两个数字彼此分开存储,以便可以拾取它们并对其执行所需的操作。因此,创建两个不同的对象来存储两个数字将是此方案的理想解决方案。

演示在OOP中使用对象和类的示例


对象与现实世界中的事物有关。例如,图形程序可以具有诸如“圆形”、“正方形”、“菜单”之类的对象。在线购物系统可能具有“购物车”,“客户”和“产品”之类的对象。
声明对象(也称为实例化类)
创建类的对象时,该类被称为实例化。所有实例都共享类的属性和行为。但是这些属性的值(即状态)对于每个对象都是唯一的。单个类可以具有任意数量的实例。
范例:

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

Dog tuffy;

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

使用new初始化对象

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

// Java 展示对象声明
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类是所有类的直接或间接父类) )。

  1. 使用new关键字:这是创建对象的最简单方法。通过使用此方法,可以调用所需的构造函数。语法:
    ClassName ReferenceVariable = new ClassName();
    // Java 代码展示创造和访问实例成员
    // 父类
    class Dog {
        // Dog有两个fields
        String dogName;
        int dogAge;
        // 构造函数
        Dog(String name, int age)
        {
            this.dogName = name;
            this.dogAge = age;
        }
    }
    // 测试代码
    public class Test {
        public static void main(String[] args)
        {
            // 创建Dog类的对象
            Dog ob1 = new Dog("Bravo", 4);
            Dog ob2 = new Dog("Oliver", 5);
            // accessing the object data through reference
            System.out.println(ob1.dogName + ", " + ob1.dogAge);
            System.out.println(ob2.dogName + ", " + ob2.dogAge);
        }
    }

    输出:

    Bravo, 4
    Oliver, 5

     

  2. 使用Class.newInstance()方法:用于动态创建新类。它可以调用任何无参数的构造函数。此方法返回在其上调用newInstance()方法的 Class类对象,该对象将返回作为命令行参数传递的该类的对象。抛出异常的原因:
    如果传递的类不存在,则将发生ClassNotFoundException。如果传递的类不包含默认构造函数,则将发生
    InstantiationException,因为newInstance()方法在内部调用该特定类的默认构造函数。如果驾驶类无权访问指定类的定义,则将发生IllegalAccessException语法:
    ClassName ReferenceVariable =
                       (ClassName) Class.forName("PackageName.ClassName").newInstance();
    // Java展示如何使用newInstance()
    // Base class
    class Example {
        void message()
        {
            System.out.println("Hello 芒果 !!");
        }
    }
    // 测试代码
    class Test {
        public static void main(String args[])
        {
            try {
                Class c = Class.forName("例子");
                Example s = (Example)c.newInstance();
                s.message();
            }
            catch (Exception e) {
                System.out.println(e);
            }
        }
    }

    输出:

    Hello 芒果 !!

     

  3. 将newInstance()方法用于Constructor类:这是创建对象的一种反映方式。通过使用它,可以调用参数化私有构造函数。它使用InvocationTargetException包装抛出的异常。它由不同的框架使用:Spring,Hibernate,Struts等。Constructor.newInstance()方法优先于Class.newInstance()方法。语法:
    Constructor constructor = ClassName.class.getConstructor();
     ClassName ReferenceVariable = constructor.newInstance();

    例:

    // Java 代码展示如何使用Constructor.newInstance()方法
    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationTargetException;
    public class ConstructorExample {
        // 抛出不同的异常
        public static void main(String[] args)
            throws NoSuchMethodException,
                   SecurityException,
                   InstantiationException,
                   IllegalAccessException,
                   IllegalArgumentException,
                   InvocationTargetException
        {
            Constructor constructor = ExampleClass.class
                                          .getConstructor(String.class);
            ExampleClass exampleObject = (ExampleClass)constructor
                                             .newInstance("芒果For芒果");
            System.out.println(exampleObject.getemp_name());
        }
    }
    class ExampleClass {
        // 私有变量被声明
        private String emp_name;
        public ExampleClass(String emp_name)
        {
            this.emp_name = emp_name;
        }
    
        public String getemp_name()
        {
            return emp_name;
        }
    
        public void setemp_name(String emp_name)
        {
            this.emp_name = emp_name;
        }
    }

    输出:

    芒果For芒果

     

  4. 使用clone()方法:用于克隆对象。这是复制对象的最简单,最有效的方法。在代码中, java.lang.Cloneable接口必须由要创建其对象克隆的类实现。如果未实现Cloneable接口,则clone()方法将生成 CloneNotSupportedException语法:
    ClassName ReferenceVariable = (ClassName) ReferenceVariable.clone();

    例:

    // Java展示如何使用clone()方法
    class Employee implements Cloneable {
        int emp_id;
        String emp_name;
        // 默认构造器
        Employee(String emp_name, int emp_id)
        {
            this.emp_id = emp_id;
            this.emp_name = emp_name;
        }
        public Object clone() throws CloneNotSupportedException
        {
            return super.clone();
        }
    }
    // 测试代码
    public class Test {
        public static void main(String args[])
        {
            try {
                Employee ob1 = new Employee("芒果", 201);
                // 创建o2,指向
                Employee ob2 = (Employee)ob1.clone();
                System.out.println(ob1.emp_id + ", " + ob1.emp_name);
                System.out.println(ob2.emp_id + ", " + ob2.emp_name);
            }
            catch (CloneNotSupportedException c) {
                System.out.println("异常: " + c);
            }
        }
    }

    输出:

    201, 芒果
    201, 芒果

     

  5. 使用反序列化:要反序列化对象,请首先在类中实现一个可序列化的接口。在此方法中,没有构造函数用于创建对象。语法:
    ObjectInputStream in = new ObjectInputStream(new FileInputStream(FileName));
    ClassName ReferenceVariable =(ClassName)in.readObject();

    例:

    // Java展示使用反序列化deserialization
    import java.io.*;
    // 父类
    class Example implements Java.io.Serializable {
        public int emp_id;
        public String emp_name;
        // 默认构造器
        public Example(int emp_id, String emp_name)
        {
            this.emp_id = emp_id;
            this.emp_name = emp_name;
        }
    }
    // 测试函数
    class Test {
        public static void main(String[] args)
        {
            Example object = new Example(1, "芒果文档");
            String filename = "file1.ser";
            // 序列化
            try {
                // 在一个文件中保存对象
                FileOutputStream file1 = new FileOutputStream(filename);
                ObjectOutputStream out = new ObjectOutputStream(file1);
                // 序列化对象
                out.writeObject(object);
                out.close();
                file1.close();
                System.out.println("已被序列化");
            }
            catch (IOException ex) {
                System.out.println("IOException异常");
            }
            Example object1 = null;
            // 反序列化
            try {
                // 读取对象
                FileInputStream file1 = new FileInputStream(filename);
                ObjectInputStream in = new ObjectInputStream(file1);
                // 反序列化方法
                object1 = (Example)in.readObject();
                in.close();
                file1.close();
                System.out.println("对象被读取");
                System.out.println("Employee ID = " + object1.emp_id);
                System.out.println("Employee Name = " + object1.emp_name);
            }
            catch (IOException ex) {
                System.out.println("IOException is caught");
            }
            catch (ClassNotFoundException ex) {
                System.out.println("ClassNotFoundException is caught");
            }
        }
    }

    对象和类之间的差异