Java的面向对象编程模式OOP的10大要点

OOP是完全不同于functional-programming的编程模式。

1.OOP入门

传统的思维认为:programming Algorithms + Data Structures = Programs。

1.1 类

java的所有class都继承自cosmic-superclass

1.2 对象

对象的三个特性:behavior,state, identity

1.3 识别对象

分析问题的首要原则,首先是名词,其次是相对应的动词。

编程就是这么简单,动词与名词。

1.4 类的关系

- /Dependence/ (“uses--a”)
- /Aggregation/ (“has--a”)
- /Inheritance/ (“is--a”)

2.预定义的类

Math是典型的预定义类。

2.1 对象与对象变量

jshell> System.out.println(new Date())
Wed Sep 09 22:31:56 SGT 2020

jshell> String s = new Date().toString();
s ==> "Wed Sep 09 22:44:27 SGT 2020"

此处有意思的地方上,单单只声明一个变量:

Date deadline; // deadline doesn't refer to any object
deadline = new Date();
deadline = birthday;


2.2 LocalData类

计时的逻辑与日历的逻辑分别处理。

jshell> LocalDate newYearsEve = LocalDate.of(1999, 12, 31);
newYearsEve ==> 1999-12-31

Date虽然也有day与month,但是deprecate。

2.3 Mutator and Accessor Methods

函数只有两个作用,mutator和accessor(scheme中称之为selector)

LocalDate aThousandDaysLater = newYearsEve.plusDays(1000);

虽然加上了1000天,但是并不变更原先的值。

3.自定义类

类可不是仅有main方法。接下来介绍'workhorse-class":

3.1.雇员类:

类的基本结构为:

class ClassName

   field_1
   field_2
   . . .
   constructor_1
   constructor_2
   . . .
   method_1
   method_2
   . . .

写出来的结构为:

class Employee
{
   // instance fields
   private String name;
   private double salary;
   private LocalDate hireDay;
   // constructor
   public Employee(String n, double s, int year, int month, int day)
   {
      name = n;
      salary = s;
      hireDay = LocalDate.of(year, month, day);
   }
   // a method
   public String getName()
   {
      return name;
   }
   // more methods
   . . .
}

这比python更加通俗易懂,没有啰哩啰嗦的init方法。

语法上需要注意:单个文件内,public-class只能有一个。

3.2.用多个source-files:

通常,程序员喜欢将类分别放置到不同的source-file中,编译的时候用:

javac Employee*.java

javac就是linux中的make。

3.3.剖析Employee类

Behaviors全部用public,field全部用private:

public Employee(String n, double s, int year, int month, int day)
public String getName()
public double getSalary()
public LocalDate getHireDay()
public void raiseSalary(double byPercent)

private String name;
private double salary;
private LocalDate hireDay;

3.4.构造器

构造器的名字与class命名一致:

public Employee(String n, double s, int year, int month, int day)
{
   name = n;
   salary = s;
   hireDay = LocalDate.of(year, month, day);
}

调用的方法:

new Employee("James Bond", 100000, 1950, 1, 1)

注意写构造器的时候,不要shadow掉原先的值:

public Employee(String n, double s, . . .)
{
   String name = n; // ERROR
   double salary = s; // ERROR
   . . .
}

3.5.用var声明变量

java10之前的写法为:

Employee harry = new Employee("Harry Hacker", 50000, 1989, 10, 1);

java10之后,可以如此写:

var harry = new Employee("Harry Hacker", 50000, 1989, 10, 1);

如此,避免重复输入Employee。

3.6.处理null引用

首先null会报错:

LocalDate birthday = null;
String s = birthday.toString(); // NullPointerException

处理空集的方法:

public Employee(String n, double s, int year, int month, int day)
{
   name = Objects.requireNonNullElse(n, "unknown");
   . . .
}

“tough-love”的模式:

public Employee(String n, double s, int year, int month, int day)
{
   Objects.requireNonNull(n, "The name cannot be null");
   name = n;
   . . .
}

3.7.显式与隐式参数

此处“Implicit and Explicit Parameters”的提法甚妙。

public void raiseSalary(double byPercent)
{
   double raise = salary * byPercent / 100;
   salary += raise;
}

number007.raiseSalary(5);

double raise = *number007*.salary * 5 / 100;
number007.salary += raise;

riaseSalary有两个参数,number007(implicit)与byPercent(explicit)。

将implicit显性标注出来,我们用this:

public void raiseSalary(double byPercent)
{
   double raise = *this*.salary * byPercent / 100;
   *this*.salary += raise;
}

3.8.Encapsulation的种种益处:

Access到下面的field:

public String getName()
{
   return name;
}
public double getSalary()
{
   return salary;
}
public LocalDate getHireDay()
{
   return hireDay;
}

通常,需要以下的结构:

- A private data field;

- A public field accessor method; and

- A public field mutator method.

虽然比直接public定义field的策略比起来,看似多此一举。然而,当我们修改field的时候,只须变更getName方法,而不必修改其内部的实现方式。

String firstName;
String lastName;

第二点优势是当对Mutator修改的时候,可以二次Check。

比如setSalary,需要检查salary不小于0.

3.9.基于类的Access-Privileges

令人惊奇的属性:

class Employee
{
   . . .
   public boolean equals(Employee other)
   {
      return name.equals(other.name);
   }
}

从此object的method,可以调用其他object的属性。

if (harry.equals(boss)) . . .

3.10.Private Method

需要隐藏内部实现的时候用private

3.11.Final-Instance-Field

class Employee
{
   private final String name;
   . . .
}

例如员工的姓名则属于不能更改的filed。

展开阅读全文

页面更新:2024-05-12

标签:空集   模式   显性   提法   动词   写法   变量   要点   名词   属性   逻辑   对象   声明   参数   结构

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top