第6章 类与对象

对象的概念

  • 万事万物皆对象
  • 对相同类型的对象进行抽象就是类
  • 面向对象是一种思想,是基于面向过程而言的,就是说面向对象是将功能等通过对象来实现,将功能封装进对象之中,让对象去实现具体的细节;
  • 对象作为程序的基本单位,将程序和数据封装其中,以提高程序的重用性,灵活性和可扩展性。

    面向对象与面向过程的典型例子对比

    青椒炒牛肉示例
    青椒炒牛肉示例

    属性概念

  • 即特征,相同类型对象具有的各种特征。每个对象的每个属性都拥有特定值

    方法概念

  • 即对象执行的操作。

    对象概念

  • 用来描述客观事物的一个实体,由一组属性和方法构成

    实例化概念

  • 类是创建对象的模板,一个类可以创建多个对象。
  • 对象是类的实例化。

    面向对象三大基本知识

    封装

  • 封装性指的是隐藏了对象的属性和实现细节,仅对外提供公共的访问方式,这样就隔离了具体的变化,便于使用,提高了复用性和安全性。

    继承

  • 两种事物间存在着一定的所属关系,那么继承的类就可以从被继承的类中获得一些属性和方法;这就提高了代码的复用性。
  • 继承是作为多态的前提的。

    多态

  • 继承是作为多态的前提的。父类或接口的引用指向了子类对象,这就提高了程序的扩展性,也就是说只要实现或继承了同一个接口或类,那么就可以使用父类中相应的方法,提高程序扩展性。

    一个简单的面向对象编码方式代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    package neu_day01.OnClass;

    /**
    * @author Jinrui Zhang
    * @create 2020-10-05 14:44
    */
    public class Circle {
    double radius;
    public void zc(){
    double c = 2*Math.PI*radius;
    System.out.println(c);
    }
    public void mj(){
    double s =Math.PI*Math.pow(radius,2);
    System.out.println(s);
    }

    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    package neu_day01.OnClass;

    /**
    * @author Jinrui Zhang
    * @create 2020-10-05 13:41
    */
    class CircleTest {
    public static void main(String[] args) {
    Circle c = new Circle();
    c.radius=10;
    c.zc();
    c.mj();
    }
    }

    类的定义

    1
    2
    3
    4
    5
    [修饰符] class 类名
    {
    //属性定义(声明)
    //方法定义(声明)
    }

属性定义的语法:

[修饰符] 类型 属性名= [初值] ;
类型可以是任何类型,包括类。
属性有默认值。

方法定义的语法:

1
2
3
4
5
[修饰符] 返回值类型 方法名(参数列表)  
{
//语句(组);
return 语句;
}

创建对象

创建对象的语法:

类名 对象名 = new 类名();
调用对象属性和方法的语法:
对象名.属性名
对象名.方法名

构造方法语法

1
2
3
4
[修饰符] 类名(参数列表)  
{
//具体实现;
}

构造方法举例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public Employee()

{
name="小明";
age=32;
salary=2000;
}

public Employee(String n,int a,double s)
{
name=n;
age=a;
salary=s;
}

构造方法-要点

  • 构造方法名与类名一致
  • 构造方法没有返回值类型
  • 如果没有定义构造方法,系统会生成一个默认的无参的构造方法
  • 如果在定义类时定义了带参的构造方法,系统将不会提供无参的构造方法
  • 构造方法只能用new在创建对象时调用,不能通过对象名调用

    变量的作用域

  • 属性:
    类的作用域,有默认值
  • 局部变量(变量):
    语句块的作用域,没有默认值

    变量的初始化

    变量的初始化

    关键字this

    关键字this

    示例代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public class Platypus {
    String name;
    Platypus(String name)
    {
    this.name=name;
    }
    Platypus()
    {
    this("John/Mary Doe");
    }
    public static void main(String args[]) {
    Platypus p1 = new Platypus("digger");
    Platypus p2 = new Platypus();
    }
    }

static 关键字

静态属性

  • 用static修饰的属性,也称为类属性
  • 用于描述一类对象共享的属性
  • 比如:员工的最低工资,学生的学校名称等等
    可通过类名直接调用,也可通过对象调用

    创建与使用

    类方法的创建:
    1
    2
    3
    4
    static void setMin(double min)    
    {
    min_salary=min;
    }
    类方法的使用:
    1
    2
    3
    Employee .setMin(600);
    Employee e1=new Employee ();
    e1.setMin(600);
    静态方法
  • 用static修饰的方法,也叫类方法
  • 静态方法中不能访问非静态成员
  • 如果一个方法中没有访问非静态成员,则这个方法可以声明成静态的

    static 方法相关要点

    创建
  • 静态属性和静态方法在第一次使用类的时候创建,所有这个类的对象共享
  • 非静态属性和非静态方法在创建对象的时候创建,每个对象之间独立

使用

  • 在类外,静态属性和静态方法可以通过类名直接调用,也可以通过对象名调用。
  • 在类外,非静态属性和非静态方法只能通过对象名调用。

限制

  • 静态方法中不能直接访问本类的非静态成员。
  • 构造方法不能是静态的。

建议

  • 描述对象共享的属性,一般声明成静态的。
  • 如果方法中没有直接访问本类的非静态成员,一般可以声明成静态的。

    Java静态类初始化器与终结器

    静态类初始化器语法结构:
    1
    2
    3
    4
    static
    {
    //语句
    }
    静态类初始化器没有返回值,没有参数,其中的变量必须是static型,静态成员变量和静态初始化块级别相同。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class Test 
    {
    public static int i;
    static
    {
    i = 10;
    }
    }
    public class Test
    {
    public static int i = 10;
    }
    这两段代码没什么区别, 两段示例代码编译之后的字节码完全一致。

测试示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Account {
static int num = 0;
public Account() {
num++;
System.out.println("aa");
}
static {
num = 100;
System.out.println("bb");
}
}

public class cam2 {
public static void main(String args[]) {
Account a = new Account();
System.out.println(a.num);
Account b = new Account();
System.out.println(b.num);
System.out.println(Account.num);
}
}

输出结果:

bb

aa

101

aa

102

102

从输出结果可看出静态类初始化块只执行了一次。

终结器语法结构:

1
2
3
4
protected void finalize()
{
//语句
}

当垃圾达到一定数目且系统不繁忙时,垃圾回收线程会自动完成所有垃圾对象的内存释放,类似于C++中的析构函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Account {
int k = 0;
protected void finalize() {
System.out.println(k);
}
}

public class cam2 {
public static void main(String args[]) {
Account a;
a = new Account();
a.k = 1;
a = new Account();
a.k = 2;
System.gc();
}
}
输出结果为1,因为堆中的a.k = 1已为垃圾。