Java面向对象

封装、继承、多态

Posted by Zhao Zihao on February 2, 2021

面向对象

基本概念

面向对象&面向过程

  • 面向对象OOP(Object Oriented Programming):强调具备了功能的对象,以类/对象为最小单位
  • 面向过程POP(Process Oriented Programming):强调功能行为,以函数为最小单位

类&对象

  • 类(class):是对一类事物的描述,是抽象的定义
  • 对象(Object):是实际存在的该类事物的每个个体,也称为实例(instance),类的实例化也就是创建类的对象
  • 匿名对象(anonymous object):创建对象时没有显式地赋给该对象一个变量名,只能调用一次,e.g. new Person()

形参&实参

  • 形参:方法声明时的参数
  • 实参:方法调用时的实际传给形参的参数值

Java的实参值如何传入方法:

1.形参是基本数据类型,将实参类型的数据值传给形参

2.形参是引用数据类型,将实参类型的地址值传给形参

方法的重载(overload)& 方法的重写(override)

方法的重载

两同一不同:同一个类下、相同方法名;参数列表不同(个数或类型不同)

e.g. print(boolean),print(char),print(int)…

方法的重写

定义:在子类中可以根据需要对从父类中继承来的方法进行改造。程序执行时,子类的方法将覆盖父类的方法

方法的声明格式:

权限修饰符 返回值类型 方法名(形参){

​ //方法体

}

说明:

  • 子类重写方法的权限修饰符大于等于父类
  • 返回值类型:父类为void,子类为void;父类为基本数据类型,子类为相同的基本数据类型;父类为引用数据类型A类,子类为A类或A类的子类
  • 方法名和形参列表相同
  • 子类重写的方法抛出的异常小于等于父类
  • 方法体不一致

区分方法的重载和重写

  1. 二者的概念
  2. 重载和重写的规则
  3. 重载不表现为多态性,重写表现为多态性

构造器(constructor)

作用:创建对象,给对象初始化

格式:权限修饰符 类名(形参){ };

说明:

  • 如果没有显式的定义类的构造器,则系统默认提供一个空参的构造器
  • 一个类中如果有多个构造器,彼此构成重载
  • 一旦显式定义类的构造器,系统将不再提供默认的空参构造器
  • 一个类中,至少有一个构造器

封装(Encapsulation)

高内聚低耦合

  • 高内聚:类的内部数据操作细节自己完成,不允许外部干涉
  • 低耦合:仅对外暴露少量的方法用于使用

设计思想

隐藏对象内部的复杂性,只对外公开简单的接口

比如,将类的属性私有化(private),提供公共的(public)方法来获取(getXxx)和设置(setXxx)此属性的值

class Person{
  private int age;
  public int getAge(){
    return age;
  }
  public void setAge(int age){
    this.age = age;
  }
}

权限修饰符

权限修饰符 类内部 同一个包 不同包子类 同一个工程
private      
default(缺省)    
protected  
public

继承(Inheritance)

优点

  • 减少代码的冗余,提高代码的复用性
  • 便于功能的拓展
  • 为之后多态性的使用,提供了前提

格式:class A extends B{ }

说明

  • 当子类A继承父类B以后,子类A就获取了B中的结构(属性,方法)。特殊地,父类中private的属性、方法,子类也获取了,只是因为封装性的影响,使得子类不能直接调用父类的结构
  • 子类继承父类以后,还可以声明自己特有的属性,方法,实现功能的拓展
  • Java中的类只支持单继承,接口可以多继承

多态(Polymorphism)

理解为:一个事物的多种形态,实现代码的通用性

对象的多态性:父类的引用指向子类的对象。e.g. Person p = new Man();

使用

前提:类的继承关系;方法的重写

当调用子类、父类同名同参数的方法时,实际执行子类中重写父类的方法

体现

  • Object类中定义的public boolean equals(Object obj)
  • JDBC:使用Java程序操作(获取数据库连接,CRUD)数据库(MySQL,SQLServer,Oracle)
  • 抽象类、接口的使用(抽象类、接口不可以实例化)

部分关键字和其他

this

  • 理解为:当前对象的
  • 用来修饰:属性、方法、构造器

super

  • 理解为:父类的
  • 用来修饰:属性、方法、构造器

instanceof

  • 作用:a instanceof A:判断a是否是A的实例,返回true/false
  • 使用场景:为避免向下转型时出现ClassCastException的异常,一般先判断
  • 例子:class A extends B,如果a instanceof A是true,则a instanceof B也是true

static

用来修饰属性、方法、代码块、内部类。随着类的加载而加载

  • static 属性:静态属性。当创建了类的多个对象,多个对象共享同一个静态变量。当通过某一个对象修改静态变量时,会导致其他对象调用此静态变量是已经修改过了的
  • static 方法:静态方法。随着类的加载而加载,可以通过“类.静态方法“调用,不需要new对象。静态方法中,只能调用静态的方法或属性,不能使用this,super

1.开发中,如何确定一个属性是否声明为static?

属性是可以被多个对象所共享的,不会随着对象的不同而不同的,例如:银行利率,最低存款金额

2.开发中,如何确定一个方法是否声明为static?

操作静态属性的方法,通常设置为static

  • static 代码块:静态代码块。随着类的加载而加载,只执行一次

final

用来修饰类、方法、属性

  • 修饰类:该类不可以被其他类继承
  • 修饰方法:该方法不可以被重写
  • 修饰属性:该变量为常量
  • static final 属性:全局常量

包装类(wrapper)

作用:使基本数据类型有了类的特点

基本数据类型 包装类
byte Byte
short Short
int Integer
long Long
float Float
double Double
boolean Boolean
char Character

相互转换关系:

基本数据类型to包装类:自动装箱

包装类to基本数据类型:自动拆箱

//自动装箱
Integer total = 99;
//自动拆箱
int totalCount = total;

基本数据类型toString类:’+’

String类to基本数据类型:例子:Integer.parseInt()

包装类toString类:toString()

== & equals()

  • ==既可以比较基本数据类型(比较值),也可以比较引用数据类型(比较内存地址)
  • equals()只能比较引用数据类型
  • 像String,Date,File,Wrapper等都重写了Object类中的equals()方法,重写以后,比较的不是两个引用地址,而是“实体内容”

toString()

  • 当我们输出一个对象的引用时,实际上是当前对象.toString()
  • 像String,Date,File,Wrapper等都重写了Object类中的toString()方法,重写以后,使得返回实体内容

abstract

用来修饰类、方法

  • abstract 类:抽象类。该类不可以实例化。一定有构造器,便于子类实例化时调用

  • abstract 方法:抽象方法。

    只有方法的声明,没有方法体。e.g. public abstract void eat();

    包含抽象方法的类,一定是抽象类;抽象类中可以没有抽象方法

    若子类重写了父类中所有的抽象方法,可实例化;如果没有,子类需要用abstract修饰

接口(interface)

说明
  • Java中,接口和类是并列关系
  • 定义接口中的成员:JDK7之前,只能定义全局常量和抽象方法;JDK8之后,还可以定义静态方法,默认方法
  • 接口中不能定义构造器,意味着接口不可以实例化
  • Java开发中,接口通过让类去实现(implement)。如果实现类覆盖了接口中所有的抽象方法,则可以实例化;如果没有,则仍为一个抽象类
  • Java可以实现多个接口。e.g. class A extends B implement C,D,E{ }
  • 接口与接口之间可以继承,而且可以多继承
  • 接口的具体使用,体现多态性
interface A{
  int x = 0;
}
class B{
  int x = 1;
}
class C extends B implements A{
  public void printX(){
    System.out.println(super.X);//1
    System.out.println(A.x);//0
  }
  //...other methods
}
抽象类&接口
  • 相同点:不能实例化,都可以被继承
  • 不同点
  抽象类 接口
构造器 不能声明
继承性 单继承 多继承