一聚教程网:一个值得你收藏的教程网站

热门教程

Java学习笔记之对象与类

时间:2022-06-29 02:55:41 编辑:袖梨 来源:一聚教程网

一、类

类(class)是构造对象的蓝图或模板。由类构造(construct)对象的过程就是创建类的实例(instance)的过程。

封装(encapsulation)是与类有关的一个重要概念。形式上来说,封装是把数据和行为组合在一个包中,并对对象的使用者隐藏了数据的实现方式。对象的数据称为实例域(instance field),操作数据的过程称为方法(method)。

继承(inheritance)使得Java中的一个类可以通过拓展另一个类而来。实际上,Java中所有的类都是继承了一个最原始的超类——Object。继承而来的新类具有基类的全部属性和方法。

二、对象

对象的三个主要特性:

1.行为(behavior)——对对象施加哪些操作或方法?
2.状态(state)——施加方法时,对象实例域如何变化?
3.标识(identity)——如何辨别具有相同行为和状态的不同对象?
三、类之间的关系

常见的有三种:

1.依赖(uses-a)—— 一个类的方法需要操纵另一个类的对象;
2.聚合(has-a)—— 一个类的对象包含另一个类的对象;
3.继承(is-a)—— 具有另一个类的全部属性和方法,拓展而来,并可以添加额外的功能。
四、自定义类

1. 类定义形式

 代码如下 复制代码
class example
{
      constructor1
      constructor2
      ...
      method1
      method2
      ...
      field1
      field2
      ...
}

例如:

 代码如下 复制代码
class Student
{
    //构造器
    public Student(String n,int num,int year,int month,int day)
    {
         name = n;
         number = num;
         GregorianCalendar calendar = new GregorianCalendar(year,month-1,day);
         birthday = calendar.getTime();
    }
    //方法
    public String getName()
    {
         return name;
    }
    public int getNumber()
    {
         return number;
    }
    public Date getBirthday()
    {
         return birthday;
    }
    //域
    private String name;
    private int number;
    private Date birthday;
}

2.  隐式参数和显式参数

 代码如下 复制代码
public void setNumber(int n)
{
    number = n;
}Student student = new Student("Jiankun Lei",136524,1991,1,1);
student.setNumber(1000);

//student为隐式参数,1000为显式参数隐式(implicit)参数,出现在方法名前的类对象;显式(explicit)参数是在方法名后括号中的参数。

3. 基于类的访问权限

记住:方法可以访问所调用对象的私有数据。也就是说一个类的方法可以访问所属类的所有对象的私有数据。

例如可以定义判断两个学生的equals的方法:

 代码如下 复制代码
boolean equals(Student other)
{
      return number.equals(other.number); //number是Student类的私有数据
}

4. final实例域

将类中的实例域定义为final。构造对象时必须初始化这样的域,构造后,不能再修改。

 代码如下 复制代码
class Student
{
      ...
      private final String name;
}

5. 静态域与静态方法

静态域:将域定义为static,每个类只能有一个这样的域。它属于类,不属于任何独立的对象。

 代码如下 复制代码
class Employee
{
      ...
      private int id;
      private static int nextId;
      ...
}public void setId()
{
      id = nextId;
      nextId++;
}

 
静态常量

 代码如下 复制代码
public class Math
{
      ...
      public static final double PI = 3.14159265358979323846;  //Math.PI
      ...
}

我们常用的System.out也是静态常量:

 代码如下 复制代码
public static System
{
      ...
      public static final PrintStream out = ... ;
      ...
}

静态方法:不能对对象实施操作。没有隐式参数。没有this参数的方法。静态方法不能访问实例域,但是能够访问自身类的静态域。

 代码如下 复制代码
public static int getNextId()
{
      return nextId;
}

Main方法:也是静态的,经常用于类的单元测试。

 代码如下 复制代码
public class Application
{
      public static void main(String[] args)
      {
             //construct objects here
             ...
      }
}

6. 对象构造

重载(overloading):在一个类中,多个方法具有相同的名字,不同的参数。

默认域初始化:在构造器中没有显式地给域赋予初值,那么就会被自动地赋为默认值:数值为0,布尔值为false,对象引用为null。

默认构造器:没有参数的构造器。

public Student()
{
      name = "";
      number = 0;
      birthday = new Date();
}

注意:类没有构造器时,系统就会提供一个默认的构造器对类进行默认域初始化。但是,如果类中至少有一个构造器,而没有默认构造器,那么系统是不会提供默认构造器的。
 

显式域初始化:可以直接在类定义中给域赋予初值,也可以调用方法对域进行初始化。

 代码如下 复制代码
class Employee
{
      ...
      private String name = "none"; //C++是不能直接初始化实例域的
}class Employee
{
      static int assignId()
      {
           int tmp = nextId;
           nextId++;
           return tmp;
      }
      ...
      private int id = assignId();
}

调用另一个构造器:如果构造器的第一个语句形如this(...),这个构造器将调用同一个类的另一个构造器。

 代码如下 复制代码
public Employee(double s)
{
       //调用 Employee(String,double)
       this("Employee #" + nextId, s);
       nextId++;
}

初始化块(initialization block):Java初始化数据域除了在构造器,在声明中,还有初始化块这种方式。初始化块在构造器之前运行,即初始化块运行后再调用构造器。

 代码如下 复制代码

class Employee
{
       ...
       public Employee(...)
       {
              ...
       }
       ...
       private int id;
       private String name;
       private static int nextId;

       //初始化块
       {
             id = nextId;
             nextId++;
       }
}

 
调用构造器的具体步骤:

1.所有数据域被初始化为默认值(0,false,null);
2.按照在类中的声明顺序,依次执行所有域的初始化语句和初始化块;
3.如果构造器的第一行调用了第二个构造器,则执行第二个构造器;
4.执行构造器主体。
没有main方法的“Hello,World”程序:

 代码如下 复制代码
public class Hello
{
      static
      {
            System.out.println("Hello,World");
      }
}

对象析构与finalize方法:C++中,有显式的析构器方法,经常用于回收分配给对象的存储空间。由于Java有自动的垃圾回收器,不需要人工回收内存,所以Java不支持析构器。但是可以在类中添加finalize方法。finalize方法在垃圾回收器清除对象之前调用。这个方法很少用。

五、 包

包(package)将类组织在一起,便于管理代码。使用包的主要原因是确保类名的唯一性。

1. 类的导入

一个类可以访问所属包中的所有类和其他包中的共有类(public class)。

有两种方式导入包:

① 在每个类前添加完整的包名

java.util.Date today = new java.util.Date();② import 语句导入包

import java.util.*;Date today = new Date();当然,还可以导入一个包中的特定类,而不是整个包

import java.util.Date;注意:Java的import语句和C++中的#include是有不同含义的。C++中,#include将外部特性的声明加载进来,这是因为C++编译器无法查看任何文件的内部,除了正在编译的文件以及在头文件中明确包含的文件。Java编译器可以查看其他文件的内部,import语句实际上是告诉它去哪里查看。

2. 静态导入

import语句不仅可以导入类,还可以导入静态方法和静态域。例如导入System类中的静态方法和静态域。

import static java.lang.System.*; 3. 将类放入包中

package com.jklei.java; //目录结构 com/jklei/java

编译test.java

javac  test.java编译器会自动查找文件com/jklei/java/Employee.java并进行编译。

4. 包作用域

访问修饰符public和private进行标记。标记为public的部分可以被任何类使用;标记为private的部分只能被定义它们的类使用。如果没有指定public或private,这个部分(类、方法或变量)可以被同一个包中的所有方法访问。

类路径和文档注释略过

5. 类设计技巧

① 将数据设计为私有(private)—— 有较好的封装性

② 一定要对数据进行初始化

③ 不要在类中使用过多的基本数据类型(如:String,int,double等)

④ 使用标准格式对类进行定义

//书写顺序
共有访问特性部分
包作用域访问特性部分
私有访问特性部分

//在每个部分,具体顺序
实例方法
静态方法
实例域
静态域⑤ 将职责过多的类进行分解 —— 确保每一个类都有独立而明确的概念

⑥ 类名体现职责 —— 如Date、Order,Student,Teacher等

热门栏目