Java-面向对象
核心思想:找适合的对象做适合的事情。
自定义类
自定义类的三步骤:
1、自定义类
class 类名 {
// 事物的公共属性使用变量描述
// 事物的公共行为使用函数描述
}
2、通过类创建对象
类名 变量名 = new 类名();
3、访问(设置)对象的属性或调用对象的功能。
抽象类 用abstract修饰
应用场景:
描述一类事物的时候,该种事物存在某种行为,但是该行为目前不是具体的行为,那么就可以抽取该种行为的声明,但是不去实现该行为,这种行为就叫抽象行为,该类就叫抽象类
好处: 强制要求子类必须实现基类的抽象方法。
注意事项:
- 如果一个函数没有方法体,该函数必须使用abstract修饰,把该函数修饰成抽象的函数。
- 如果一个类中出现了抽象的函数,那么该类也必须使用abstract修饰。
- 如果一个非抽象类继承了一个抽象类,那么必须把抽象类的所有抽象方法都实现。
- 抽象类中可以存在非抽象的方法。
- 抽象类可以不存在抽象方法。
- 抽象类不能创建对象。
- 抽象类是存在构造方法的,其构造方法是提供给其子类创建对象使用的。
匿名对象
定义:没有引用类型变量指向的对象。
需要注意的事项:
- 一般不会给匿名对象赋予属性值,因为永远无法取到。
- 两个匿名对象永远都不可能是同一个对象。
应用场景: - 当一个对象需要调用一个方法,调用完这个对象就不再使用了,可以使用匿名对象,节省内存空间。
- 可以作为实参调用一个函数。
面向对象的三大特征:封装、继承、多态
封装
权限修饰符:控制变量的可见范围。
- public 修饰的成员变量或者方法任何人都可以直接访问。
- private 修饰的成员变量或者方法只能本类进行直接访问。
封装的步骤:
- 使用private修饰需要封装的属性。
- 提供一个公共的方法设置或者获取该私有的成员属性。
命名规范:
set属性名();
get属性名();
封装的好处:
- 提高数据安全性
- 操作简单
- 隐藏了实现
继承:is a 关系
继承的格式:
class 类名1 extends 类名2 {
// 类内容
}
类名1称为子类,类名2称为基类(父类/超类);
注意事项:
- 只有真正存在继承关系的时候才能使用继承。
- 基类私有的成员不能被继承。
- 基类的构造函数不能被继承。
- 创建子类对象时默认会先调用父类无参的构造函数。
方法重写: 子类中重写父类的方法
什么时候使用方法重写: 父类的功能不能满足子类的需求时。
方法重写的注意事项:
- 方法名和形参列表必须一致。
- 子类的权限修饰符必须要大于或者等于父类方法的权限修饰符。
- 子类的返回值类型必须要小于或等于父类的返回值类型。
4.子类抛出的异常类型必须要小于或等于父类抛出的异常类型。
多态
定义:父类的引用类型变量指向了子类的对象。
前提:必须存在继承或者实现关系。
注意事项:
- 多态情况下,子父类存在同名的成员时,访问的都是父类的成员,只有当成员为非静态方法时,访问的是子类方法。
- 多态情况下,不能访问子类特有的成员。
多态应用: - 用于形参类型时,可以接收更多类型的数据。
- 用于返回值类型时,可以返回更多类型的数据。
构造函数
作用:给对应的对象初始化。
定义格式:
修饰符 函数名() {
函数体;
}
注意细节:
- 构造函数没有返回值。
- 构造函数函数名必须要与类名一样。
- 构造函数是在创建对象的时候自动调用的,不能手动调用。
- 没有给类写构造方法时,那么Java编译器在编译时会为该类添加一个无参的构造函数。
- 构造函数可以以函数重载的形式存在多个的,创建对象时只调用参数对应的那个。
代码块
- 构造代码块
- 局部代码块
- 静态代码块
构造代码块
作用:给对象进行统一的初始化。
格式:
{
构造代码块;
}
放的位置:在类的任何一个方法外面,和类的属性位置平齐。
注意:
- 构造代码块中的代码在编译时,会放在构造函数中执行,而且是放在前面执行,构造函数中的代码最后执行。
- 成员变量的显示赋值和代码块中的赋值,是按照代码书写的顺序执行的。
局部代码块
大括号位于方法内,一般不会用。
静态代码块
this 关键字
代表所属函数的调用者,即谁调用就this就指向谁。
作用:
- 指向它的调用者。
- 在一个构造函数中,通过this(形参);方式,调用本类中的其他构造函数。
注意:
- this(形参); 必须放在第一行。
- 不能调用本构造函数,否则出现死循环。
super 关键字
super关键字代表了父类空间的引用。
作用:
- 子类中存在着和父类同名的成员时,默认访问子类的成员,通过super关键字指定访问父类的成员。
- 创建子类对象时,默认会调用父类无参的构造函数,通过super指定调用父类带参的构造函数。
instanceof 关键字
判断一个对象是否属于指定的类型。
使用前提:判断的对象与指定的类别必须要存在继承或实现的关系。
使用格式:
对象 instanceof 类名
final 修饰符
用法:
- 修饰基本类型的变量时,该变量初始化后其值不可再次修改。
- 修饰引用类型的变量时,该变量不能改变其指向的对象。
- 修饰一个方法时,该方法不能被重写。
- 修饰一个类时,该类不能被继承。
常量的修饰符一般为: public static final
static 修饰符
应用场景:当变量需要被所有对象共享时使用。
作用:
- static修饰符修饰的成员变量,在实例化时不会每个对象都维护一份,而是只在数据共享
区维护一份,所有的同类型的对象共享。
静态成员变量的访问方式:
- 点 对象.变量名
- 类直接访问 类名.变量名 (非静态成员变量不能使用此方式访问)
- static修饰符修饰方法时
访问方式1:使用对象进行访问
对象名.静态函数名();
访问方式2:类名进行访问
类名.静态函数名字
注意事项:
- 静态函数可以使用对象或类名进行访问,而非静态函数不能使用类名访问。
- 静态函数内可以直接访问静态成员,不能直接访问非静态成员。
- 非静态函数可以对静态成员和非静态成员都可以直接访问。
- 静态函数不能出现this和super关键字。
静态数据的生命周期:
- 静态的数据是在类文件加载时执行一次,优先于对象存在的。
静态成员数据存储的位置:
静态成员数据存在方法区的数据共享区,而非静态成员变量存储在堆内存中。
main函数
格式:
public static void main() {
代码区;
}
解读:
public:公共的,权限很大,在任何情况下都可以访问。
static: 静态,可以让jvm调用main函数时,不需要通过对象调用,直接调用既可。
设计模式
单例设计模式(饿汉单例设计模式)
解决的问题:保证一个类在内存中只有一个对象。
设计模式步骤:
- 私有化构造函数
- 声明本类的引用类型变量(private static),并使用该变量指向本类对象,即在本类中实例化本身。
- 提供一个公共的静态的方法获取本类的对象。
class Single {
private static Single s = new Single(); // 在本类中实例化本身
private Single { } // 私有化构造函数
public static Single getInstance () { // 提供一个公共静态方法获取本类对象
return s;
}
}
// 使用
Single s1 = Single.getInstance();
单例设计模式(懒汉单例设计模式)
步骤:
- 私有化构造函数
- 声明本类的引用类型变量,不创建本类的对象
- 提供公共静态的方法获取本类对象,返回之前,先判断是否创建了本类对象,若没有创建则创建,若已经创建了,则直接返回。
class Single {
private static Single s = null; // 在本类中实例化本身
private Single { } // 私有化构造函数
public static Single getInstance () { // 提供一个公共静态方法获取本类对象
if (s == null) {
s = new Single();
}
return s;
}
}
// 使用
Single s1 = Single.getInstance();
注意:推荐使用饿汉单例设计模式,因为懒汉设计模式可能存在线程安全问题。
接口
为了拓展功能。
定义格式:
interface 接口名 {
}
注意事项:
- 接口是一个特殊的类。
- 接口中的成员变量默认修饰符为:public static final,就是说接口中的成员变量都是常量。
- 接口中的方法都是抽象的方法,默认修饰符为:public abstract。
- 接口不能创建对象,因为接口中的方法是抽象,成员变量时常量。
- 接口是没有构造方法的。
- 接口是给类去使用的, 非抽象类实现一个接口时,必须把类中的所有方法都实现。
接口的作用:
- 程序的解耦。
- 定义约束规范。
- 拓展功能。
类使用接口格式:
class 类名 implements 接口名 {
// 代码
}