面向对象程序设计(object oriented programming简称OOP),对象是一个由信息(变量)及对信息进行处理(方法)的描述,其本质是对现实事物的特征和变化规律建立的模型
访问权限
- 访问修饰符
访问修饰符 | 含义 | 可以修饰 |
---|---|---|
public | 公共的类 | 属性、方法 |
protected | 受保护的 | 属性、方法 |
为空 | 默认的类 | 属性、方法 |
private | 私有的 | 属性、方法 |
- 访问权限表
访问权限 | 同一个类中 | 同一个包中的不同类 | 不同包中的子类 | 不同包中的非子类 |
---|---|---|---|---|
public | √ | √ | √ | √ |
protected | √ | √ | √ | × |
为空 | √ | √ | × | × |
private | √ | × | × | × |
返回值类型
- 无返回值
void
- 基本数据类型
byte
、short
、int
、long
、float
、double
、char
、boolean
- 引用数据类型
类
、接口
、数组
方法
- 方法的定义
修饰符 返回值类型 方法名(参数类型 参数名,参数类型 参数名...){
方法体
}
- 方法的类型
- 无参无返回值
void display(){
System.out.println("Hello World");
}
- 有参无返回值
void display(String string){
System.out.println("Hello World"+string);
}
- 无参有返回值
int display(){
return 1;
}
- 有参有返回值
int display(int year){
return year;
}
- 方法
定义时的参数
称为形式参数
,简称为形参
,在方法体中使用。- 方法
调用时传递的值
称为实际参数
,简称为实参
,只需要保证满足形参的数据类型即可,与形参名无关。
类和对象
定义类(class)
[修饰符] class 类名{
//属性(变量)
//行为(方法)
}
- 属性:描述对象的特征,在程序中,通过定义变量的形式表现属性。
- 行为:描述对象的动作,在程序中,通过定义方法的形式表现行为。
创建对象(Object)
类名 对象名 = new 构造方法([参数]);
创建的对象,通过"."操作符访问类中的非私有属性和方法。
成员变量和局部变量
可用数据类型
数据类型 | 默认值 |
---|---|
整型 | 0 |
浮点型 | 0.0 |
布尔型 | false |
字符型 | 空字符 |
引用类型(数组、类、接口) | null |
- 成员变量
定义在
类
中的变量,称为成员变量
,拥有默认值
- 局部变量
定义在
方法
中的变量,称为局部变量
。默认有默认值,赋值后才能使用
面向对象三大特性
封装
- 定义
细节(变量和方法)隐藏,成员变量设置为私有(private),然后提供set和get方法来读和取。通俗的讲,封装就是不允许直接访问成员变量,必须通过set和get方法来访问;
- 特点
安全,便于重构
- 良好的封装能够减少耦合。
- 类内部的结构可以自由修改。
- 可以对成员变量进行更精确的控制。
- 隐藏信息,实现细节。
- 步骤
- 创建类,编写成员变量,给成员变量添加private修饰符
- 给所有成员变量添加setXXX方法,用于给私有的成员变量赋值
- 给所有成员变量添加getXXX方法,用于读取私有的成员变量
- 这是创建对象后,无法通过.访问属性,只能通过get/set方法
public class Person{
private int age;
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
}
使用IDEA自动生成getter/setter方法
使用鼠标在编写代码界面右键选择Generate或者快捷键Alt+Insert后,选择Getter and Setter自动生成
继承
- 定义
通过关键字extends来声明子类与父类的继承关系:子类 extends 父类
- 特点
- 所有类都有父类,即所有类都派生于Object类
- 只能单亲继承,即每一个子类只能有一个父类
- 子类只能继承父类的非private修饰的变量和方法
- 子类可以通过父类的公有get/set方法访问到父类的私有变量
- 子类可以直接使用继承的变量和方法,不需要再在子类中声明或写出
- 方法的重写和重载
- 方法重写要求(
@Override
)
方法名、参数列表、返回值必须和父类一致
访问权限不能比父类更严格(访问修饰符的范围要么一致要么更大)
不能抛出比父类更大的异常
- 方法重载要求(
@overload
)
- 方法重载要求
- 方法名相同
- 参数列表(参数类型和数量)不同
- 与返回值无关
- 构造方法(
Constructor
)
构造方法(又叫构造器)是一种特殊的方法,它的作用是在创建对象的时候 ,完成对象成员变量的初始化。
特点:
- 方法名与类名一致
- 没有返回值也没有void
- 通过new关键字调用
- 当一个类
没有
显示的声明构造方法时,java会默认创建一个无参构造方法
- 构造方法可以
重载
- this和super关键字
这两个关键字,都可以当做对象使用,也可以当做构造方法使用。
- 当做对象使用
用法:“this.属性”或“this.方法”或“super.属性”或“super.方法”
此时的this或super表示“当前类”或"父类对象"。
public class Person{
private String name;
public void setName(String name){
this.name=name;//这里的this表示当前类Person的对象
//this表示Person p = new Person();中的p
}
public String getName(){
return name;
}
}
public class Man extends Person{
public void fun(){
System.out.println(super.getName());
//这里的super表示当前类父类Person对象
//super表示Person p = new Person();中的p
}
}
- 当做构造方法使用
用法:“this([参数])或super([参数])”
此时的this([参数])或super([参数])表示当前类或当前类的父类的某个构造方法。
如果当做构造方法使用时,只能写在另一个构造方法中的第一行。
public class Person(){
private String name;
private int age;
public Person(){
//这句话表示调用Person(String name,int age)构造方法,只能放在第一行
this("小明",20);
}
public Person(String name,int age){
this.name=name;
this.age=age;
}
public void info(){
//this();//这里不能使用this(),因为不在构造方法中
System.out.println("我叫"+name);
}
}
public class Woman extends Person{
public Woman(String name,int age){
//这里的super()表示调用父类Person中的Person(String name,int age)构造方法
super(name,age);
}
}
注意:
- 如果父类中有无参数的构造方法,在子类的构造方法中,可以不写super(),系统会自动调用。
- 如果父类中有带参数的构造方法,没有无参数的构造方法,在子类的构造方法中,必须要写super(),并且赋予适当的参数。
多态
- 没有继承就没有多态,生成的对象,在调用父类方法时,如果方法被子类重写,则调用的是子类重写的方法。
- 代码当中体现多态性,其实就是一句话:父类引用指向子类对象
父类 对象名 = new 子类();
抽象abstract
- 修饰方法
使用: 访问修饰符 abstract 返回值类型 方法名(参数类型 形参名称);
- 如果一个方法的方法体无法描述,是由其子类进行重写,可以将该方法定义为抽象方法。
- 该抽象方法所在的类,也必须用abstract修饰,让其成为一个抽象类。
- 修饰类
使用: 访问修饰符 abstract class 类名{}
- 如果一个类中有抽象方法,这个类必须也是一个抽象类。
- 抽象类不能被实例化(不能创建对象)。
- 抽象类中,可以存在非抽象方法,如getter/setter或构造方法。
- 当抽象类的构造方法执行时,不会创建对象。
- 当一个类不希望创建它本身对象或在它其中有抽象方法时,就将该类定义为抽象类。
- 特点
- 修饰类:被修饰的类称为抽象类
- 抽象类不能被实例化,无法创建对象。
- 抽象类中有构造方法,在创建其子类对象时,自动调用执行。
- 抽象类中可以有抽象方法,也可以有非抽象方法。
- 抽象类的子类要么继续成为抽象类,要么重写抽象父类中的所有抽象方法。
- 修饰方法:被修饰的方法称为抽象方法
- 抽象方法没有方法体
- 抽象方法只能出现在抽象类或接口中。
- abstract不能修饰构造方法和静态方法。
接口
public interface 接口名{
//接口中只能定义公开的静态常量且要赋值,默认用public static final修饰
double PI = 3.14;
//接口中的方法默认用public abstract修饰,表示公开的抽象方法
void fun(String name);
//接口中不能定义普通方法
//void fun1(){}
//jdk1.8之后,接口中可以定义默认方法或静态方法,有方法体
default void fun2(){
}
static void fun3(){
}
}
- 使用
类A extends 类B
类A当做类B的子类,继承。
类A implements 接口A,接口B...
类A当做接口A、接口B的实现类("子类")
接口A extends 接口B
接口A通过extends继承接口B
类A extends 类B implements 接口A,接口B...
类A是类B的子类,是接口A、接口B的实现类,同时能访问这三个"父类"中的数据。
- 接口的特点:
用interface关键字声明接口
- 子类实现接口,并重写接口的所有的签名方法;
- 接口只有方法的签名和变量
- 接口的变量,会默认用public final static修饰
- 接口的签名方法,会默认用public abstract修饰
- 接口不能自身实例化,接口的实现类可以实例化
- 接口可以实现多个,而父类只有一个(单亲继承),而且必须先继承父类再实现接口
- 接口的优点
- 解决Java中的单亲继承问题(继承只能单亲继承,但是一个类可以实现多个接口)
- 接口可以实现并行开发
- 便于重构
- 抽象类和接口的异同
- 抽象类是一个类,用abstract class定义
- 有构造方法,不能创建对象,在创建子类对象时调用构造方法
- 抽象类中可以有抽象方法,也可以有普通方法
- 抽象类被子类继承时,使用extends关键字。子类必须重写父类中的所有抽象方法
- 子类只能继承一个抽象类
- 接口不是一个类,用interface定义
- 没有构造方法,不能创建对象
- 接口中的属性都是公共的静态常量
- 接口中的方法都是公共的抽象方法
- JDK1.8后,可以在接口中定义default方法和static方法
- 接口被实现类实现时,使用implements关键字。实现类必须重写父接口中的所有抽象方法
- 实现类可以实现多个接口
- 相同点
- 接口和抽象类都不能创建对象
- 接口的实现类和抽象类的子类,都需要重写抽象方法