最近老是有小伙伴问类和Object相关的问题,感觉还是很多人对此不是很明白,那我们今天就干掉这两个怪物。

类介绍

Java 程序是由若干个类组成的,类也是面向对象编程思想的具体实现。

以下为类的定义:

public class User {
   //私有属性
   private Long userId;
   private String name;
   private Integer age;
   // 构造方法
   public User() {
   }
   //有残构造方法
   public User(Long userId, String name, Integer age) {
       this.userId = userId;
       this.name = name;
       this.age = age;
   }

   //普通方法
   public void say() {
       System.out.println("hello world");
   }
   // 对外包装属性
   public String getName() {
       return this.name;
   }
}

关键字import的三种用法

单类型导入

当我们需要使用不同包下的类时,就需要使用 import 导入包或类,这个时候才能正常使用。例如,我们要使用java.util下的 ArrayList 就必须使用 import java.util.ArrayList,代码如下:

// 导入 ArrayList 类
import java.util.ArrayList;
class Test {
   public static void main(String[] args) {
       ArrayList list = new ArrayList();
   }
}

按需类型导入

如果我们在同一个类中使用了同一个包下面的较多类时候,就会使用按需类型导入。

// 用到了java.util包目录下的List、ArrayList和LinkedList类
//import java.util.ArrayList;
//import java.util.LinkedList;
//import java.util.List;
//如果不想类上有太多import,就可以直接import 包名.*
import java.util.*;
public class Test {
   public static void main(String[] args) {
       List list = new ArrayList<>();
       List list1 = new LinkedList();
   }
}

这个只是表象,其实也是一个一个的导入的,只是在代码层面看起来是一次性全部倒入了。

静态导入

import 还可以导入静态方法和静态域的功能,比如以下代码:

//**精准导入**
//直接导入具体的静态变量、常量、方法方法,注意导入方法直接写方法名不需要括号。
import static com.assignment.test.StaticFieldsClass.staticField;
import static com.assignment.test.StaticFieldsClass.staticFunction;

//或者使用如下形式:
//**按需导入**不必逐一指出静态成员名称的导入方式
//import static com.assignment.test.StaticFieldsClass.*;

public class StaticTest {
   public static void main(String[] args) {
       //这里直接写静态成员而不需要通过类名调用
       System.out.println(staticField);
       staticFunction();
   }
}

以上代码也可以顺利的执行,这也是 import 好玩的一个地方。

构造方法

构造方法也叫构造器或构造函数,它的作用是类在进行初始化的时候会调用对应的构造方法,比如以下代码:

public class User {
   //私有属性
   private Long userId;
   private String name;
   private Integer age;
   // 构造方法
   public User() {
   }
   //有参构造方法
   public User(Long userId, String name, Integer age) {
       this.userId = userId;
       this.name = name;
       this.age = age;
   }

   //普通方法
   public void say() {
       System.out.println("hello world");
   }
   public static void think() {
       System.out.println("thinking");
   }
   // 对外包装属性
   public String getName() {
       return this.name;
   }

构造方法五大原则

  1. 构造方法必须与类同名;

  2. 构造方法的参数可以没有或者有多个;

  3. 构造方法不能定义返回值(默认返回类型就是本类类型);

  4. 每个类可以有一个或多个构造方法;

  5. 构造方法总是伴随着 new 操作一起使用。

注意:如果勒种没有显示的定义构造方法,那么在编译的时候回默认为其添加一个无惨构造方法。构造方法实际开发中通常都是public修饰,还有就是我们想要单例的情况下搞成private修饰。

Object

Object 类是 Java 中的一个特殊类,它是所有类的父类,Java 中的类都直接或间接的继承自 Object 类。

Object 类的常用方法如下:

  • equals():对比两个对象是否相同

  • getClass():返回一个对象的运行时类

  • hashCode():返回该对象的哈希码值

  • toString():返回该对象的字符串描述

  • wait():使当前的线程等待

  • notify():唤醒在此对象监视器上等待的单个线程

  • notifyAll():唤醒在此对象监视器上等待的所有线程

  • clone():克隆一个新对象

关于更多 Object 的内容,如克隆(深克隆、浅克隆)、线程的几个常用方法wait、notify、notifyAll,对象比较,对象的hashCode值等。

继承

Java 中只支持单继承:即一个子类只能继承两个父类,而一个父类可以被多个子类继承。

每个人都只能有一个亲生父亲,一个父亲是可以有多个儿子的。

用法:使用 extends 关键字来实现类的继承,示例代码如下:

class Person {
   public void say() {
       System.out.println("hello");
   }
}
public class User extends Person {
   public static void main(String[] args) {
       Person user = new User();
       user.say();
   }
}

以上程序执行结果:hello

继承的注意点

  1. 单一继承性。(在Java中是不支持多继承的,通俗的说子类只能有一个父类,而父类可以有很多子类。)

  2. 支持多层继承。(继承可以一直传下去,子类有父类,父类又有父类...)

  3. 如果父类成员使用private修饰,那么子类不能被继承。(private只是对本类有效)

  4. 如果一个子类继承了父类的属性和方法还可以有自己特有的属性和方法。(不光有父类的属性(可继承的)和方法(可继承的),也有自己独有的属性和方法。)

  5. 当子类和父类的成员变量重名的时候,子类优先。(就近原则)

继承使用技巧

  • 将公共的变量或者方法提取到超类中;

  • 除非所有的方法都有继承的意义,否则不要使用继承;

  • 在方法覆盖时不要改变原有方法的预期行为。

  • 一般在写代码的时候发现代码中存在重复代码,需要向上抽取,考虑继承。

  • 当某个类的设计非常复杂的时候可以考虑继承

继承的优点

  • 代码的可重用性。

  • 使用继承可以轻松的定义子类。

  • 父类的属性和方法可以用于子类中(非private修饰)。

  • 设计应用程序变得更加简单。

设计模式中大量使用

比如:模板方法模式,就是采用继承,子类自己去实现自己的业务逻辑。