1.类
1.1 类的定义
private
:同一个类(default)
:同一个类,同一个包protected
:同一个类,同一个包,不同包的子类public
:任意位置访问- 静态(带
static
修饰符)成员变量/函数与普通成员变量/函数的区别:
所有static
成员变量/函数在类中只有一份,被所有类的对象共享;
所有普通成员变量/函数在类的每个对象中都有独立的一份;
静态函数中只能调用静态函数/变量;普通函数中既可以调用普通函数/变量,也可以调用静态函数/变量。
1.2 类的继承
每个类只能继承一个类。
class ColorPoint extends Point {
private String color;
public ColorPoint(int x, int y, String color) {
super(x, y);
this.color = color;
}
public void setColor(String color) {
this.color = color;
}
public String toString() {
return String.format("(%d, %d, %s)", super.getX(), super.getY(), this.color);
}
}
1.2.1 继承中的成员访问特点 - 成员变量
this
:调用本类成员super
:调用父类成员- 被调用的变量和方法,在子类中不存在,
super.
可以直接省略
- 被调用的变量和方法,在子类中不存在,
final
:修饰符- 修饰方法:表明该方法是最终方法,不能被重写
- 修饰类:表明该类是最终类,不能被继承
- 修饰变量:表明该变量是常量,不能再次被赋值
- 基本数据类型:数据值不可改变
- 引用数据类型(数组):地址值不可改变,但是内容可以改变
final
修饰变量的命名规范:- 如果变量名是一个单词,所有字母大写:max -> Max
- 如果变量名是多个单词,所有字母大学,中间使用下划线分割:maxValue -> MAX_VALUE
1.2.2 构造方法
- 除了
Object
类,在所有的构造方法的第一行代码,都默认隐藏了一句话super()
。通过这句话,访问父类的空参构造方法
1.3 类的多态
public class Main {
public static void main(String[] args) {
Point point = new Point(3, 4);
Point colorPoint = new ColorPoint(1, 2, "red");
// 多态,同一个类的实例,调用相同的函数,运行结果不同
System.out.println(point.toString());
System.out.println(colorPoint.toString());
}
}
1.4 抽象类
- 特殊在哪?
- 内部允许编写抽象方法
- 什么是抽象方法?
- 当我们将共性的方法,抽取到父类之后,发现这个方法在父类中无法给出具体描述,而且这个方法,还是子类必须要有的方法,就可以设计为抽象方法
- 抽象类不能实例化
- 抽象类存在构造方法
- 交给子类,通过
super
进行访问
- 交给子类,通过
- 抽象类中可以存在普通方法
- 抽象类的子类
- 要么重写抽象类中的所有抽象方法
- 要么是抽象类
abstract
关键字冲突final
private
static
:被static
修饰的方法可以直接进行类名调用,而类名调用抽象方法没有意义
abstract class Animal {
public abstract void eat();
}
class Cat extends Animal {
@Override
public void eat() {
}
}
class Dog extends Animal {
@Override
public void eat() {
}
}
2.接口
- 接口也可以继承其他接口,一个类可以实现多个接口。
- 接口没有成员变量,没有普通方法。只有抽象方法(
abstract
可以省略) - 接口不允许实例化
- 接口(
interface
)和类之间是实现关系,通过implements
关键字来完成 - 实现类(接口的子类)
- 要么重写所有的抽象方法
- 要么将实现类变成抽象类
2.1 接口的成员特点
- 成员变量:只能是常量,默认修饰符
public static final
- 构造方法:没有
- 成员方法:只能是抽象方法,默认修饰符
public abstract
2.2 类和接口之间的各种关系
- 类与类的关系:继承关系,只能单继承,但是可以多层继承
- 类和接口的关系:实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口
- 接口和接口的关系:继承关系,可以单继承,也可以多继承
2.3 接口的定义
接口中不添加修饰符时,默认为public
。
interface Role {
public void greet();
public void move();
public int getSpeed();
}
2.4 接口的继承
每个接口可以继承多个接口
interface Hero extends Role {
public void attack();
}
2.5 接口的实现
每个类可以实现多个接口
class Zeus implements Hero {
private final String name = "Zeus";
public void attack() {
System.out.println(name + ": Attack!");
}
public void greet() {
System.out.println(name + ": Hi!");
}
public void move() {
System.out.println(name + ": Move!");
}
public int getSpeed() {
return 10;
}
}
2.6 接口的多态
- 多态的前提:
- 有继承 / 实现关系
- 有方法重写
- 有父类引用指向子类对象
- 1.对象多态
Animal a1 = new Dog();
Animal a2 = new Cat();
- 好处:方法的形参定义为父类类型,这个方法就可以接收到该父类的任意子类对象
- 2.行为多态
- 好处:同一个方法,具有多种不同的表现形式,或形态的能力
- 3.多态的成员访问特点:
- 成员变量:编译看左边(父类),运行看左边(父类)
- 成员方法:编译看左边(父类),运行看右边(子类)
- 4.不能使用子类的特有成员变量和成员方法
public static void main(String[] args) {
useAnimal(new Dog());
useAnimal(new Cat());
}
public static void useAnimal(Animal a){ // Animal a = new Dog();
a.eat(); // Animal a = new Cat();
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入:1.国内订单 2.国外订单");
OrderService orderService = null;
int choice = sc.nextInt();
switch(choice) {
case 1:
// 创建国内订单的业务类
orderService = new OrderServiceImpl();
break;
case 2:
// 创建国外订单的业务量
orderService = new OverseasServiceImpl();
break;
}
// instanceof:判断左边的引用,是否是右边的数据类型
if(orderService instanceof OverseasServiceImpl){
OverseasServiceImpl osi = (OverseasServiceImpl) orderService;
osi.check();
}
orderService.create();
orderService.findOne();
orderService.findList();
orderService.cancel();
orderService.finish();
orderService.paid();
}
- 多态中的转型问题
- 如果被转的引用类型变量,对应的实际类型和目标类型不是同一种类型,那么在转换的时候就会出现
ClassCastException
异常 - 解决办法:对象名
instanceof
类型
- 如果被转的引用类型变量,对应的实际类型和目标类型不是同一种类型,那么在转换的时候就会出现
- JDK8版本接口特性:
- 1.允许定义非抽象方法,需要加入default关键字
- 作用:解决接口的升级问题
- 注意实现:
- 1.
public
可以省略,但是default
不能省略 - 2.默认方法,实现类是允许重写的,但是需要去掉
default
关键字 - 3.如果实现了多个接口,多个接口中存在相同的默认方法,实现类必须重写默认方法
- 1.
- 2.允许定义静态方法
- 理解:既然接口已经允许方法带有方法体了,干脆也放开静态方法,可以类名调用
- 注意实现:
- 1.
public
可以省略,但是static
不能省略 - 2.接口中的静态方法,只允许接口名进行调用,不允许实现类通过对象调用
- 1.
- 1.允许定义非抽象方法,需要加入default关键字
public class Test {
public static void main(String[] args) {
AInterImpl a = new AInterImpl();
a.show();
a.print();
a.method();
A.function();
}
}
interface A{
public default void method(){
System.out.println("A...method");
}
public static void function(){
System.out.println("A...function");
}
}
interface Inter {
void show();
void print();
public default void method(){
System.out.println("Inter...method");
}
}
class AInterImpl extends Object implements Inter, A {
@Override
public void show() {
System.out.println("AInterImpl...show");
}
@Override
public void print() {
System.out.println("AInterImpl..print");
}
@Override
public void method() {
super.method();
A.super.method();
Inter.super.method();
}
}
- JDK9接口特性:接口中允许定义私有方法,使用
private
关键字
interface Inter {
void show();
void print();
public default void start(){
System.out.println("start方法执行...");
log();
}
public default void end(){
System.out.println("end方法执行...");
log();
}
private void log(){
System.out.println("日志记录");
}
}
3.代码块:使用{}
括起来的代码被称为代码块
分类:
- 局部代码块(了解)
- 位置:方法中的一对大括号
- 作用:限定变量的生命周期,提早的释放内存
- 构造代码块(了解)
- 位置:类中方法外的一对大括号
- 特点:在创建对象,执行构造方法的时候,就会执行构造代码块(优先于构造方法执行)
- 作用:将多个构造方法中,重复的代码,抽取到构造代码块中,从而提升代码的复用性
- 静态代码块(掌握)
- 位置:类中方法外的一对大括号,需要加入
static
关键字 - 特点:随着类的加载而执行,虽然可以创建无数个对象,但是类只加载一次,所以也就执行一次
- 作用:对数据进行初始化
- 位置:类中方法外的一对大括号,需要加入
public class Test {
public static void main(String[] args) {
{
int num = 10;
System.out.println(num);
}
Student stu1 = new Student();
Student stu2 = new Student(10);
}
}
class Student {
static {
System.out.println("static...Student类的静态代码块");
}
{
System.out.println("Student类的构造代码块");
System.out.println("好好学习");
}
public Student(){
System.out.println("空参构造方法...");
}
public Student(int num){
System.out.println("带参构造方法...");
}
}
3.其他
3.1 static
- 被类的所有对象所共享
- 可以通过类名直接调用
- 随着类的加载而加载,优先于对象存在
- 不允许使用this关键字
static
方法中,只能访问静态成员/静态方法(直接访问)
3.2 创建类的细节
- 一个.java文件中可以编写多个class
- 保证类与类之间是平级关系
- 只能有一个被
public
修饰(因为被public
修饰的类表示文件名称)