类和对象
类:对象共同特征的描述
对象:真实存在的东西
定义类
一个java文件中可以定义多个类,但是只能一个类是public修饰,public修饰的类名必须是Java代码的文件名。
public class 类名 { |
JavaBean类
在JavaBea类中不写main方法,用来描述一类事物
标准的JavaBean:
- 类名见名知意
- 成员变量使用private修饰
- 至少提供两个构造方法(无参、带全部参数)
- 提供每一个成员变量对应的get和set方法
测试类
创建javaBean类的对象并复制调用,带main方法
封装
对象代表什么,就得封装对应的数据,并提供数据对应的行为。
例:人 画 圆:画圆这个方法应该是定义在圆类里边。【人调用了圆类中画圆的方法】
构造方法
在创建对象的时候给成员变量进行初始化的。
执行时机:创建对象的时候由虚拟机调用。
public class Stu { |
- 方法名和类名相同
- 没有返回值(不能有return待会结果数据)
- 如果没有写构造方法,虚拟机会默认给一个空参的构造方法。
- 如果已经定义了构造方法,虚拟机就不会给空参的构造方法。
- 推荐:无论是否使用,把无参构造和带全部参数的构造都写上。
对象内存图
虚拟机创建一个对象的过程
Student s = new Student()
- 加载class文件
- 申明局部变量
- 在堆内存中开辟空间
- 默认初始化
- 显式初始化
- 构造方法初始化
- 将堆内存中的地址值赋值给左边的局部变量
一个对象的内存图
两个对象的内存图
两个引用指向同一个对象
基本数据类型和引用数据类型
- 基本数据类型:数据值存在自己的空间,赋值给其他变量,也是赋的真实的值
- 引用数据类型:数据值存储在其他空间,自己的空间存储的是其他空间的地址值。
this的内存原理
this:区分局部变量和成员变量。
本质:所在方法调用者的地址值。
static
修饰成员变量(静态变量)
特点:该类被所有对象共享
调用方式:类名调用、对象名调用
静态变量是随着类的加载而加载,属于类,不属于对象。
修饰成员方法(静态方法)
特点:多用于测试类和工具类中,javaBean中很少用
调用方式:类名调用、对象调用
静态方法只能访问静态变量和静态方法
非静态方法可以访问所有的变量和方法(静态、非静态)
静态方法中没有this关键字【非静态方法虚拟机会分配一个this对象,表示当前方法调用者的地址,这个this不需要我们来赋值】
工具类
- 需要私有化构造方法(工具类的对象没有实际意义,可以通过类名直接调用工具类里的方法)
- 方法定义为静态的
继承
继承的特点
- java只支持单继承,不支持多继承,但支持多层继承
- 所有的类都直接或间接继承于Object类
子类能继承父类的东西
构造方法
父类的构造方法不能被子类继承
构造方法的访问特点
- 父类中构造方法不会被子类继承
- 子类中所有的构造方法都先默认访问父类中的无参构造,再执行自己。
- 子类构造方法的第一行默认都是:**super()**,不写虚拟机也会自动加上。
成员变量
私有和非私有的都可以直接继承,但是私有的成员变量不能被直接使用。
成员方法
只有父类中的虚方法才能被子类继承
虚方法表
非private、非static、非final
作用:提高程序的性能、
方法重写
- 重写方法、形参列表和父类一致
- 方法的访问权限子类访问权限必须大于等于父类
- 方法的返回值类型子类必须小于等于父类
- 只有被添加到虚方法表中的方法才能被重写
this、super使用总结
this:一个变量,表示当前方法调用者的地址(并不是每个对象里都有this)
super:表示父类存储空间
注意:如果使用this(…)访问本类其他构造,虚拟机就不会再添加super()了,因为this(…)访问的构造方法里就会自动加上super()
多态
多态:对象的多种表现形态
- 变量调用:编译看左边,运行看左边。
- 方法调用:编译看左边,运行看右边。
class Animal { |
理解:
Animal a = new Dog();
a是Animal类的,所以默认都会从Animal这个类中找。
成员变量:在子类对象中,会把父类中的成员变量也继承下来。
成员方法:如果子类重写方法,在虚方法表中会把父类中的方法进行覆盖。
多态的优势
- 右边可以实现解耦合
- 定义方法时,使用父类作为参数,可以接受所有的子类对象。
多态的弊端
不能调用子类特有的方法【通过强转成子类来调用子类特有的方法】
包
包就是文件夹,管理不同功能的Java类。
类的全类名 = 包名 + 类名
使用其他类的规则
- 使用同一个包中的类,不需要导包
- 使用java.lang包中的类,不需要导包
- 其他情况都需要导包
- 如果使用两个包中同名的类,需要导包
final
可以修饰方法、类、变量
- 修饰方法:表明当前方法是最终方法,不能被重写【当前的方法是一种规则, 不希望别人去改变】
- 修饰类:表明当前方法是最终类,不能被继承
- 修饰变量:被修饰的变量叫做常量,只能被赋值一次
final修饰的变量是基本类型:变量存储的数据值不能发生改变。
final修饰的变量是引用类型:变量存储的地址值不能发生改变,对象的内部可以改变。
权限修饰符
控制一个成员可以被访问的范围,可以修饰方法、变量、构造方法、内部类private < 缺省 < protected < public
代码块
- 局部代码块(淘汰)
- 构造代码块:写在成员位置的代码,优先于构造方法执行,可以把多个构造方法中重复的代码写在构造代码块中(淘汰)
public class Student { |
常用:
3. 静态代码块
需要通过static关键字修饰,随着类的加载而加载,自动触发,只执行一次。
格式:static{}
使用场景:在类加载的时候,做一些数据初始化的时候使用
class Stu { |
抽象类
将共性的方法抽象到父类之后,在父类中不确定具体的方法体,该方法就可以定义为抽象方法。
- 抽象类不能创建对象
- 抽象类可以有构造方法
- 抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
- 抽象类的子类要么重写抽象类中所有的抽象方法,要么子类也得是抽象类。
接口
接口就是一种规则。
抽象类表示一类事务,接口表示一种行为。
public interface 接口名{} |
- 接口不能实例化
- 接口和类之间是实现关系
public class 类名 implements 接口名{} |
- 接口的子类:要么重写接口中所有的抽象方法,要么是抽象类。
注意:
- 接口和类的实现关系可以是单实现,也可以是多实现。
- 实现类可以在继承一个类的同时实现多个接口。
public class 类名 extends 父类 implements 接口名1, 接口名2 {}
接口中成员的特点
- 成员变量:只能是常量,默认修饰符:
public static final
- 构造方法:没有
- 成员方法:抽象方法 或 有方法体的方法,默认修饰符:
public abstract
接口和类之间的关系
- 类和类的关系
继承关系,只能单继承,不能多继承,可以多层继承。 - 类和接口的关系
实现关系,可以单实现,也可以多实现,还可以再继承一个类的同时实现多个接口。 - 接口和接口的关系
继承关系,可以单继承,也可以多继承。
JDK8接口新增的方法
默认方法
JDK8以后:接口可以定义有方法体的方法,允许在接口中定义默认方法,需要用关键字default修饰
格式:public default 返回值类型 方法名(参数列表) {}
- 默认方法不是抽象方法,不强制重写,如果被重写,重写的时候需要去掉default关键字。
- public可以省略,default不能省略。
- 如果实现了多个接口,多个接口存在相同名字的默认方法,子类就必须对该方法进行重写。
静态方法
允许在接口中定义静态方法,需要用static修饰。
格式:public static 返回值类型 方法名(参数列表) {}
- 静态方法只能通过接口名调用,不能通过实现类 或 对象名调用。
- public可以省略,static不能省略。
接口的应用
- 接口代表规则,是行为的抽象,想要让哪个类拥有一个行为,就让这个类实现对应的接口。
- 接口多态:当一个方法的参数是接口时,可以传递接口所有实现类的对象。
适配器模式:解决接口与接口实现类之间的矛盾问题
场景:假设一个接口有多个抽象方法,想让某个继承这个接口的类只实现其中一个方法。
interface Inter { |
内部类
在一个类的里面,再定义一个类。
内部类表示的事物是外部类的一部分,单独出现没有任何意义。
内部类可以访问外部类的成员,包括私有。
外部类要访问内部类的成员,必须创建对象。
// 外部类 |
成员内部类
写在成员位置,属于外部类的成员。
class Outer { |
静态内部类
只能访问外部类中静态变量和静态方法,如果访问非静态的需要创建对象。
创建静态内部类对象的格式:外部类名.内部类名 对象名 = new 外部类名.内部类名()
调用非静态方法的格式:先创建对象,用对象调用
调用静态方法的格式:外部类名.内部类名.方法名()
局部内部类
- 将内部类定义在方法里就叫局部内部类,类似于方法里的局部变量。
- 外界无法直接使用,需要在方法内部创建对象并使用。
- 可以直接访问外部类的成员,也可以访问方法里的局部变量。
匿名内部类(重点)
匿名内部类的本质就是隐藏了名字的内部类。
new 类名或接口名() { |
interface Swim { |
使用场景,如果定义的类或接口只使用一次,可以使用匿名内部类简化代码。