目录
继承
提高代码的重用性,减少一些重复代码的书写
继承就是Java中提供了一个关键字extends,用这个关键字,可以让一个类和另一个类建立起父子关系。

权限修饰符


继承的特点
1.单继承
Java是单继承模式:一个类只能继承一个直接父类
2.多层继承
Java不支持多继承,但支持多层继承
3.祖宗类
Java中所有的类都是object类的子类
4.就近原则
优先访问自己类中,自己类中的没有才会访问父类



继承后子类访问成员的特点:就近原则
1、在子类方法中访问其他成员(成员变量、成员方法),是依照就近原则的。
先子类局部范围找,然后子类成员范围找,然后父类成员范围找,如果父类范围还没有找到则报错。
2、如果子父类中,出现了重名的成员,会优先使用子类的,如果此时一定要在子类中使用父类的怎么办?
可以通过super关键字,指定访问父类的成员:
super.父类成员变量/父类成员方法
方法重写
当子类觉得父类中的某个方法不好用,或者无法满足自己的需求时,子类可以重写一个方法名称、参数列表一样的方法,去覆盖父类的这个方法,这就是方法重写。
重写小技巧:使用Override注解,他可以指定java编译器,检查我们方法重写的格式是否正确,代码可读性也会更好。
方法重写的其它注意事项
子类重写父类方法时,访问权限必须大于或者等于父类该方法的权限( public > protected > 缺省 )。
重写的方法返回值类型,必须与被重写方法的返回值类型一样,或者范围更小。
私有方法、静态方法不能被重写,如果重写会报错的。
子类构造器的特点
子类的全部构造器,都会先调用父类的构造器,再执行自己。
子类构造器是如何实现调用父类构造器的:
默认情况下,子类全部构造器的第一行代码都是 super() (写不写都有) ,它会调用父类的无参数构造器。
如果父类没有无参数构造器,则我们必须在子类构造器的第一行手写super(….),指定去调用父类的有参数构造器。
子类构造器调用父类构造器的场景应用场景

super(…)调用父类有参数构造器的常见应用场景是什么?
为对象中包含父类这部分的成员变量进行赋值。
补充知识:this(…)调用兄弟构造器
任意类的构造器中,是可以通过this(…) 去调用该类的其他构造器的。

this(...)和super(…)使用时的注意事项:
this(…) 、super(…) 都只能放在构造器的第一行,因此,有了this(…)就不能写super(…)了,反之亦然。
1、this(…)的作用是什么?
在构造器中调用本类的其他构造器。
2、this(…)和super(…)的使用需要注意什么?
都必须放在构造器的第一行。
多态

使用多态的好处
在多态形式下,右边对象是解耦合的,更便于扩展和维护。
定义方法时,使用父类类型的形参,可以接收一切子类对象,扩展性更强、更便利。
多态下会产生的一个问题,怎么解决?
多态下不能使用子类的独有功能。
解耦合;使用父类类型的变量作为方法的形参时,可以接收一切子类对象。
多态下的类型转换问题

1、类型转换有几种形式?能解决什么问题?
自动类型转换、强制类型转换。
可以把对象转换成其真正的类型,从而解决了多态下不能调用子类独有方法的问题。
2、强制类型转换需要注意什么?
存在继承/实现时,就可以进行强制类型转换,编译阶段不会报错。
但是,运行时,如果发现对象的真实类型与强转后的类型不同会报错(ClassCastException)。
3、强制类型转换前?Java建议我们做什么事情?
使用instanceof判断当前对象的真实类型:对象 instanceof 类型 。
综合案例—加油站支付小模块
某加油站为了吸引更多的车主,推出了如下活动,车主可以办理金卡和银卡。
卡片信息包括:车牌号码、车主姓名、电话号码、卡片余额。
金卡办理时入存金额必须>=5000元,银卡办理时预存金额必须>=2000元,金卡支付时享受8折优惠,银卡支付时享受9折优惠,金卡消费满200元可以提供打印免费洗车票的服务。
需求:请使用面向对象编程,完成该加油站支付机的存款和消费程序。
为了实现上述需求,我们可以定义几个类来代表卡片、车主信息以及支付逻辑。下面是一个简单的Java程序示例,它使用了面向对象的方法来建模这个加油站的支付系统。首先,我们需要创建一个Card接口,然后是GoldCard和SilverCard两个具体类来实现这个接口。接着,我们还需要一个Owner类来存储车主的信息,并且有一个PaymentMachine类来处理存款和消费的操作。
// 卡片接口
interface Card {
void recharge(double amount);
boolean consume(double amount, boolean printTicket);
}
// 金卡类
class GoldCard implements Card {
private String plateNumber;
private double balance;
public GoldCard(String plateNumber, double initialAmount) {
if (initialAmount < 5000) {
throw new IllegalArgumentException("Initial deposit for Gold Card must be at least 5000.");
}
this.plateNumber = plateNumber;
this.balance = initialAmount;
}
@Override
public void recharge(double amount) {
balance += amount;
}
@Override
public boolean consume(double amount, boolean printTicket) {
double discountAmount = amount * 0.8; // 享受8折优惠
if (balance >= discountAmount) {
balance -= discountAmount;
if (printTicket && discountAmount >= 200) {
System.out.println("Providing a free car wash ticket.");
}
return true;
} else {
System.out.println("Insufficient balance.");
return false;
}
}
public double getBalance() {
return balance;
}
}
// 银卡类
class SilverCard implements Card {
private String plateNumber;
private double balance;
public SilverCard(String plateNumber, double initialAmount) {
if (initialAmount < 2000) {
throw new IllegalArgumentException("Initial deposit for Silver Card must be at least 2000.");
}
this.plateNumber = plateNumber;
this.balance = initialAmount;
}
@Override
public void recharge(double amount) {
balance += amount;
}
@Override
public boolean consume(double amount, boolean printTicket) {
double discountAmount = amount * 0.9; // 享受9折优惠
if (balance >= discountAmount) {
balance -= discountAmount;
return true;
} else {
System.out.println("Insufficient balance.");
return false;
}
}
public double getBalance() {
return balance;
}
}
// 车主信息类
class Owner {
private String name;
private String phoneNumber;
private Card card;
public Owner(String name, String phoneNumber, Card card) {
this.name = name;
this.phoneNumber = phoneNumber;
this.card = card;
}
public Card getCard() {
return card;
}
}
// 支付机类
class PaymentMachine {
public static void main(String[] args) {
// 创建银卡实例
SilverCard silverCard = new SilverCard("京A12345", 2500);
// 创建金卡实例
GoldCard goldCard = new GoldCard("沪B67890", 5500);
// 创建车主实例
Owner owner1 = new Owner("张三", "13800138000", silverCard);
Owner owner2 = new Owner("李四", "13900139000", goldCard);
// 消费操作
owner1.getCard().consume(200, false); // 使用银卡消费
owner2.getCard().consume(250, true); // 使用金卡消费并打印洗车票
// 输出余额
System.out.println("Silver Card Balance: " + ((SilverCard)owner1.getCard()).getBalance());
System.out.println("Gold Card Balance: " + ((GoldCard)owner2.getCard()).getBalance());
}
}
final
final 关键字是最终的意思,可以修饰:类、方法、变量。
修饰类:该类被称为最终类,特点是不能被继承了。
修饰方法:该方法被称为最终方法,特点是不能被重写了。
修饰变量:该变量有且仅能被赋值一次。
final修饰变量的注意
final修饰基本类型的变量,变量存储的数据不能被改变。
final修饰引用类型的变量,变量存储的地址不能被改变,但地址所指向对象的内容是可以被改变的。
常量

设计模式
单例设计模式


什么是设计模式,设计模式主要学什么 ? 单例模式解决了什么问题 ?
具体问题的最优解决方案。
解决了什么问题? 怎么写?
确保某个类只能创建一个对象。

单例怎么写? 饿汉式单例的特点是什么?
把类的构造器私有;定义一个静态变量存储类的一个对象;提供一个静态方法返回对象。
在获取类的对象时,对象已经创建好了。
单例有啥应用场景,有啥好处?
任务管理器对象、获取运行时对象。
在这些业务场景下,使用单例模式,可以避免浪费内存。

懒汉单例模式的特点是什么?
要用类的对象时才创建对象(延迟加载对象)
懒汉单例模式怎么写?
把构造器私有。
定义一个类变量用于存储对象。
提供一个类方法,保证返回的是同一个对象。
枚举类

枚举类的特点

枚举类的常见应用场景

抽象类

抽象类的注意事项、特点
抽象类中不一定要有抽象方法,有抽象方法的类必须是抽象类。
类有的成员:成员变量、方法、构造器,抽象类都可以有。
抽象类最主要的特点:抽象类不能创建对象,仅作为一种特殊的父类,让子类继承并实现。
一个类继承抽象类,必须重写完抽象类的全部抽象方法,否则这个类也必须定义成抽象类。
使用抽象类的好处

模板方法设计模式

写法
1、定义一个抽象类。
2、在里面定义2个方法:
一个是模板方法:把共同的实现步骤放里面去。
一个是抽象方法:不确定的实现步骤,交给具体的子类来完成。
建议使用final关键字修饰模板方法,为什么?
模板方法是给子类直接使用的,不能被子类重写。
一旦子类重写了模板方法,模板方法就失效了。
总结:
1、模板方法设计模式解决了什么问题?
解决方法中存在重复代码的问题。
2、模板方法设计模式应该怎么写?
定义一个抽象类。
在里面定义2个方法,一个是模板方法:放相同的代码里,一个是抽象方法:具体实现交给子类完成。
3、模板方法建议使用什么关键字修饰?为什么
建议使用final关键字修饰模板方法。
接口

接口的好处
弥补了类单继承的不足,一个类同时可以实现多个接口,使类的角色更多,功能更强大。
让程序可以面向接口编程,这样程序员就可以灵活方便的切换各种业务实现(更利于程序的解耦合)。
接口新增的三种方法
1.默认方法(实例方法):使用default修饰,默认会被加上public修饰。
注意:只能使用接口的实现类对象调用
2.私有方法:必须用private修饰(JDK9开始支持)
3.类方法(静态方法):使用static修饰,默认会被加上public修饰。
注意:只能用接口名来调用

小结:
1、JDK8开始,接口中新增了哪些方法?
默认方法:使用default修饰,使用实现类的对象调用。
静态方法:static修饰,必须用当前接口名调用
私有方法:private修饰,jdk9开始才有的,只能在接口内部被调用。
他们都会默认被public修饰。
2、JDK8开始,接口中为啥要新增这些方法?
增强了接口的能力,更便于项目的扩展和维护。
接口的注意事项
1、接口与接口可以多继承:一个接口可以同时继承多个接口[重点]。
2、一个接口继承多个接口,如果多个接口中存在方法签名冲突,则此时不支持多继承,也不支持多实现。
4、一个类继承了父类,又同时实现了接口,如果父类中和接口中有同名的默认方法,实现类会优先用父类的。
5、一个类实现了多个接口,如果多个接口中存在同名的默认方法,可以不冲突,这个类重写该方法即可。
代码块

内部类

成员内部类

静态内部类

局部内部类

匿名内部类

匿名内部类在开发中的常见形式


案例—使用comparator接口的匿名内部类实现对数组进行排序

函数式编程


小结
1、什么是函数式编程?有是好处?
使用Lambda函数替代某些匿名内部类对象,从而让程序代码更简洁,可读性更好。
2、Lambda表达式是啥?有什么用?怎么写?
JDK8新增的一种语法,代表函数;可以用于替代并简化函数式接口的匿名内部类。
3、什么样的接口是函数式接口?怎么确保一个接口必须是函数式接口?
只有一个抽象方法的接口就是函数式接口。
在接口上加上@FuncationalInterface注解即可。
案例—使用Lambda简化comparator接口的匿名内部类

Lambda表达式的省略规则
作用:用于进一步简化Lambda表达式的写法。
具体规则
参数类型全部可以省略不写。
如果只有一个参数,参数类型省略的同时“()”也可以省略,但多个参数不能省略“()”
如果Lambda表达式中只有一行代码,大括号可以不写,同时要省略分号“;”如果这行代码是return语句,也必须去掉return。
静态方法引用
类名::静态方法
使用场景
如果某个Lambda表达式里只是调用一个静态方法,并且“→”前后参数的形式一致,就可以使用静态方法引用。
实例方法引用
对象名::实例方法。
使用场景
如果某个Lambda表达式里只是通过对象名称调用一个实例方法,并且“→”前后参数的形式一致,就可以使用实例方法引用。
特定类的方法引用
特定类的名称::方法
使用场景
如果某个Lambda表达式里只是调用一个特定类型的实例方法,并且前面参数列表中的第一个参数是作为方法的主调,后面的所有参数都是作为该实例方法的入参的,则此时就可以使用特定类型的方法引用。
构造器引用
类名::new
使用场景
如果某个Lambda表达式里只是在创建对象,并且“→”前后参数情况一致,就可以使用构造器引用。
常用API
String
String代表字符串,它的对象可以封装字符串数据,并提供了很多方法完成对字符串的处理。
1、创建字符串对象,封装字符串数据
2、调用String提供的操作字符串数据的方法
String创建字符串对象的方式

String提供的常用方法

小结:
1. String是什么,可以做什么?
代表字符串,可以用来创建对象封装字符串数据,并对其进行处理。
2. String类创建对象封装字符串数据的方式有几种?
方式一: 直接使用双引号“...” 。
方式二:new String类,调用构造器初始化字符串对象。
ArrayList
集合是一种容器,用来装数据的,类似于数组。
1、创建ArrayList对象,代表一个集合容器
2、调用ArrayList提供的方法,对容器中的数据进行增删改查操作
ArrayList集合
1、集合是什么,有什么特点?
一种容器,用来存储数据的
集合的大小可变。
2、ArrayList是什么? 怎么使用?
是集合中最常用的一种,ArrayList是泛型类,可以约束存储的数据类型。
创建对象: 调用无参数构造器public ArrayList()初始化对象
调用增删改查数据的方法
GUI编程
GUI,全称Graphical User Interface,是指图形用户界面。
通过图形元素(如窗口、按钮、文本框等)与用户进行交互。
与命令行界面(CLI)相比,GUI更加直观、友好。
为什么学习GUI编程?
增强用户体验
广泛应用于桌面应用程序开发
Java提供了强大的GUI编程支持
Java的GUI编程包
AWT(Abstract Window Toolkit)
提供了一组原生的GUI组件,依赖于操作系统的本地窗口系统
Swing
基于AWT,提供了更丰富的GUI组件,轻量级组件,不依赖于本地窗口系统
常用的Swing组件
JFrame: 窗口
JPanel: 用于组织其他组件的容器
JButton: 按钮组件
JTextField: 输入框
JTable: 表格

常见的布局管理器
布局管理器(Layout Manager)它们可以决定组件在容器中的布局方式,避免了手动设置每个组件的位置和大小,从而简化了GUI设计过程。
常见的布局管理器
FlowLayout
BorderLayout
GridLayout
BoxLayout
事件处理
GUI编程中,事件的处理是通过事件监听器(Event Listener)来完成的。
常用的时间监听器对象
点击事件监听器 ActionListener
按键事件监听器 KeyListener
鼠标行为监听器 MouseListener
事件的几种常见的写法
第1种:直接提供实现类,用于创建事件监听对象
第2种:直接使用匿名内部类的对象,代表事件监听对象
第3种:自定义窗口,让窗口对象实现事件接口
布局管理器简介
什么是布局管理器?
布局管理器(Layout Manager)是Java Swing中用于控制容器中组件排列和大小的对象。它们决定了组件在容器中的布局方式,避免了手动设置每个组件的位置和大小,从而简化了GUI设计过程。
常见的布局管理器
FlowLayout
-
简介: FlowLayout 是最简单的布局管理器,它按水平方向从左到右排列组件,当一行排满时,自动换到下一行。
-
特点
-
默认居中对齐,可以设置为左对齐或右对齐。
-
适用于需要简单排列的场景。
-
-
代码示例
import java.awt.*;
public class FlowLayoutExample {
public static void main(String[] args) {
JFrame frame = new JFrame("FlowLayout Example");
frame.setSize(400, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
frame.add(new JButton("Button 1"));
frame.add(new JButton("Button 2"));
frame.add(new JButton("Button 3"));
frame.add(new JButton("Button 4"));
frame.add(new JButton("Button 5"));
frame.setVisible(true);
}
}
BorderLayout
-
简介: BorderLayout 将容器划分为五个区域:东、南、西、北和中(East, South, West, North, Center)。每个区域只能添加一个组件,未添加组件的区域保持空白。
-
特点
-
适用于需要在特定区域布局组件的场景。
-
中间区域会占据所有剩余的空间。
-
-
代码示例
import java.awt.*;
public class BorderLayoutExample {
public static void main(String[] args) {
JFrame frame = new JFrame("BorderLayout Example");
frame.setSize(400, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JButton("North"), BorderLayout.NORTH);
frame.add(new JButton("South"), BorderLayout.SOUTH);
frame.add(new JButton("East"), BorderLayout.EAST);
frame.add(new JButton("West"), BorderLayout.WEST);
frame.add(new JButton("Center"), BorderLayout.CENTER);
frame.setVisible(true);
}
}
GridLayout
-
简介: GridLayout 将容器划分为等大小的网格,每个网格中可以添加一个组件,所有组件大小相同。
-
特点
-
适用于需要均匀排列组件的场景。
-
行和列的数量可以指定。
-
-
代码示例
java复制代码import javax.swing.*;
import java.awt.*;
public class GridLayoutExample {
public static void main(String[] args) {
JFrame frame = new JFrame("GridLayout Example");
frame.setSize(400, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(2, 3)); // 2行3列的网格
frame.add(new JButton("Button 1"));
frame.add(new JButton("Button 2"));
frame.add(new JButton("Button 3"));
frame.add(new JButton("Button 4"));
frame.add(new JButton("Button 5"));
frame.add(new JButton("Button 6"));
frame.setVisible(true);
}
}
BoxLayout
-
简介: BoxLayout 能够沿着单一轴线(X轴或Y轴)排列组件。可以创建水平(X轴)或垂直(Y轴)排列的布局。
-
特点
-
适用于需要沿单一方向排列组件的场景。
-
可以通过添加垂直或水平间隔(Glue、Strut)来调整组件间距。
-
-
代码示例
import java.awt.*;
public class BoxLayoutExample {
public static void main(String[] args) {
JFrame frame = new JFrame("BoxLayout Example");
frame.setSize(400, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); // 垂直排列
panel.add(new JButton("Button 1"));
panel.add(Box.createVerticalStrut(10)); // 添加垂直间隔
panel.add(new JButton("Button 2"));
panel.add(Box.createVerticalStrut(10));
panel.add(new JButton("Button 3"));
panel.add(Box.createVerticalStrut(10));
panel.add(new JButton("Button 4"));
frame.add(panel);
frame.setVisible(true);
}
}
这些示例展示了布局管理器在Java Swing中的基本用法。你可以根据实际需求选择合适的布局管理器来设计你的GUI应用程序。

1777

被折叠的 条评论
为什么被折叠?



