🏀 final关键字
它是一个修饰符,代表最终的意思,可以修饰变量,类,方法
final关键字的特点
- 被final关键字修饰的变量是常量
常量的分类:
- 字面值常量
- 整数常量
- 小数常量
- 字符常量
- 字符串常量
- 空常量
- 布尔常量
- 自定义常量
- 被final修饰的变量
被final修饰的类不能被继承
被final修饰的成员方法不能被重写
final的注意事项
如果一个成员变量,在被定义的时候,并没有给初始值,会编译报错,我们必须给其赋值
赋值方式有几种?
- 显示初始化 final int age = 18;
- 有参构造赋值 public void eat(int age){ this.age=age}
🚵♀️ 代码块
由一对花括号括号起来的,就称为代码块
代码块的分类
- 局部代码块
- 构造代码块
- 静态代码块
- 同步代码块(学习多线程的时候讲解)
局部代码块
定义在方法中的代码,就称为局部代码块
class Demo {
public void print() {
{
//局部代码块
}
}
}
- 局部代码块的作用是什么?
能够让局部变量,更早的在内存中消失,节省内存空间
构造代码块
定义在类中,方法外的代码块,就称为构造代码块
class Demo {
{
//构造代码块
}
public void print() {
//构造方法将在构造代码块后执行,与顺序无关
}
}
构造代码块是在创建对象的时候执行,并且是优先于构造方法先执行
- 构造代码块的作用是什么?
可以将构造方法中的共性内容进行抽取,放入到构造代码块中,节省代码的编写
举例子:
public class Demo06 {
public static void main(String[] args) {
Child c1 = new Child();
Child c2 = new Child("张三");
Child c3 = new Child("哪吒", 18);
}
}
class Child {
{
System.out.println("哭"); //抽取代码块
}
public Child() {
//System.out.println("哭");
}
public Child(String name) {
//System.out.println("哭");
}
public Child(String name, int age) {
//System.out.println("哭");
}
}
静态代码块
被静态修饰的构造代码块,就称为静态代码块
class Demo {
static {
//静态代码块
//这里写 加载配置文件的一些代码
}
public void print() {
}
}
- 静态代码块的作用是什么?
给数据进行初始化,当数据只需要被初始化一次的时候,之后可以重复使用的时候,就可以使用静态代码块
- 静态代码块是什么时候执行的?
当.class文件从本地磁盘加载到方法区中形成字节码文件对象的时候,静态代码块会随之执行
- 为什么静态代码块只会执行一次?
因为字节码文件只加载一次,并且优先于所有的对象存在于内存中,比构造方法先执行
🥁 抽象类
被abstract关键字所修饰的类就是个抽象类
有抽象方法的类就是抽象类
- 什么是抽象方法?
没有方法体的方法,且被abstract关键字修饰的方法就是抽象方法
抽象类的特点
- 抽象类和抽象方法都要由abstract关键字来修饰
```java
abstract class Person { //抽象类
public abstract void eat(); //抽象方法,没有方法体
}//正常情况下,方法体永远不会执行
class Student extends Person { public void eat() { System.out.println(“吃肉”) } }
class Teacher extends Person { public void eat() { System.out.println(“吃米饭”); } }
class Demo { public static void main(String[] args) { Student s = new Student();
Person p = new Student();
Teacher t = new Teacher();
}
}
2. 抽象类可以没有抽象方法,但是有抽象方法的类一定是抽象类
```java
abstract class Person {
public void eat() {}
public void sleep() {}
public abstract void drink();
}
如果一个抽象类中没有任何抽象方法,适配器设计模式
构造方法都是public修饰,但是如果是private修饰的话,要么是工具类,提供了static的成员方法,可以通过类名调用,要么就是单例设计模式
- 抽象类因为没有方法体,所以不能创建对象
- 一个类想要继承一个抽象类,要么该类也是一个抽象类,要么该类是一个普通类,但是必须重写所有的抽象方法
抽象类的成员特点
- 成员变量
里面可以有静态的成员变量
里面可以有非静态的成员变量
里面可以自定义常量
- 成员方法
抽象类中可以有抽象方法,也可以里面可以有成员方法(非抽象方法)。
- 构造方法
有构造方法,但是,抽象类不能创建对象,为什么会有构造方法?
因为抽象类的构造方法是用来让子类去调用的,然后给抽象类中的成员变量进行初始化,好提供给子类使用
abstract class Person {
int i;
public Person() {
}
public abstract void eat();
public abstract void play();
public void sleep(){
}
public void drink(){
}
}
class Student extends Person {
public Student(){
super();
}
}
abstract关键字和不能哪些关键字共存
- abstract不能和private关键字共存:
因为被abstract关键字修饰的方法是抽象方法,子类是一定要重写的,如果该方法同时又被private修饰的话,子类还重写不了,所以冲突
abstract class Fu {
private abstract void print();//报错
}
class Zi extends Fu {
public void print() {
}
}
- abstract不能和static关键字共存:
因为被static关键字所修饰的方法可以通过类名直接调用,但是同时被abstract关键字修饰的方法,没有方法体的,调用一个没有方法体的方法???
abstract class Fu {
public abstract static void print();//报错
}
Fu.print();
- abstract不能和final关键字共存:
因为被abstract关键字修饰的方法是抽象方法,子类是一定要重写的,如果该方法同时又被final修饰的话,子类还重写不了,所以冲突
abstract class Fu {
public final abstract void print();//报错
}
class Zi extends Fu {
public void print() {
}
}
🤼♂️ 接口
比抽象类更加抽象的表现形式,就是接口
接口的定义格式
interface 接口名 {
}
接口不是类
接口的使用格式
interface Inter {
}
class Zi implements Inter {
}
接口的特点
- 接口不能创建对象
一个类想要实现一个接口,要么该类是一个抽象类,要么该类是一个普通类,就必须重写接口中的所有的抽象方法
public class demo03 {
public static void main(String[] args) {
Zi zi = new Zi();
zi.print();
}
}
interface Inter {
public abstract void print();
public abstract void show();
}
class Zi implements Inter {
@Override
public void print() {
System.out.println("重写后的print方法");
}
@Override
public void show() {
System.out.println("重写后的show方法");
}
}
接口的成员特点
- 成员变量:
接口中的所有的变量全部都是自定义常量
默认修饰符:public static final
(public static final) int i = 1;
static final int j = 1;
int x = 1;
- 成员方法:
接口中的所有的方法都是抽象方法(错误的解释)
默认修饰符:public abstract
public abstract void aaa();
abstract void bbb();
public void ccc();
void ddd();
- 构造方法:
接口中没有构造方法
继承的是object方法
接口与接口,类与类,接口与类之间的关系
- 类与类:继承关系,单继承,不可以多继承,也可以实现其他的接口
```java
class Fu {
public void eat() {
} }System.out.println("吃肉");
class Zi extends Fu {
}
2. 类与接口:实现关系,支持单实现,也可以多实现
```java
interface Inter {
}
interface Inter1 {
}
class Zi implements Inter, Inter1 {
}
- 接口与接口:继承关系,支持单继承,也可以多继承 ```java interface A { public abstract void eat(); }
interface B {
}
interface C extends A, B {
}
class Zi implements C { public void eat() {
}
}
<a name="uhHQq"></a>
## 我们什么时候使用接口,什么时候使用类(包含抽象类)
1. 当两个类之间存在"is a",就要定义类,两个类之间是继承关系
1. 接口是额外扩展的功能,本身该类不具备这个功能,而且还不是"is a"的关系,就需要去实现这样的接口了
举例子:
```java
public class demo04 {
public static void main(String[] args) {
Dog d = new Dog();
d.eat();
d.fly();
d.play();
}
}
abstract class Animal {
public abstract void eat();
public void drink() {
System.out.println("喝水");
}
}
class Dog extends Animal implements Fly{
public void play(){
System.out.println("捡骨头");
}
public void eat(){
System.out.println("狗食");
}
public void fly(){
System.out.println("上下飞");
}
}
class Cat extends Animal implements Fly{
public void sleep() {
System.out.println("睡觉");
}
public void eat(){
System.out.println("猫食");
}
public void fly() {
System.out.println("斜着飞");
}
}
class Pig1 extends Animal implements Fly {
public void gong() {
System.out.println("拱树");
}
public void eat() {
System.out.println("猪食");
}
public void fly(){
System.out.println("横着飞");
}
}
interface Swin {
public abstract void swimming();
}
interface Fly {
public abstract void fly();
}
🏆 包
包本质上就是文件夹
怎么创建包
文件夹与文件夹之间用.来分隔
com.woniu
包命名规则
一般都是公司的域名倒着写,去掉www
com.woniuxy.XXXOOO
注意:包名都是小写的
导包
import 包名.类名
如果两个类不再同一个包的下面,类A想使用类B,就要先导入类B
com.aaa
-A
com.bbb
-B
🛀 访问权限修饰符
public > protected > 默认的(什么都不写) > private
修饰符 | 同一个类 | 同一个包不同类 | 不同包有继承 | 不同包无继承 |
---|---|---|---|---|
private | yes | |||
default | yes | yes | ||
protected | yes | yes | yes | |
public | yes | yes | yes | yes |
以后开发,一个类的各个组成部分都都什么修饰符来修饰:
- 类是用public修饰的
- 属性是用private修饰的
- 构造方法是用public修饰的
- 偶尔会用private修饰的
- 成员方法是用public修饰的
🥇 内部类
一个类写在另外一个类的里面,里面的类就是内部类
内部类的特点
内部类可以直接访问外部类的成员,包括私有的
但是,外部类不能直接使用内部类的成员,但是可以间接使用
内部类的分类
成员内部类
定义在类中,方法外的内部类
class Outer {
class Inner {
}
}
成员内部类的使用
public/protected/默认:
class Demo {
public static void main(String[] args) {
Outer.Inner oi = new Outer().new Inner();
System.out.println(oi.i);
oi.print();
}
}
class Outer {
class Inner {
int i = 1;
public void print() {
System.out.println("约吗");
}
}
}
class Outer {
static class Inner {
int i = 1;
public void print() {
System.out.println("约吗");
}
}
}
class Demo {
public static void main(String[] args) {
Inner inner = new Inner();
System.out.println(inner.i);
inner.print();
}
}
import com.inner.Outer.Inner;
class Demo {
public static void main(String[] args) {
Outer.Inner oi = new Outer.Inner();
System.out.println(oi.i);
oi.print();
}
}
class Outer {
static class Inner {
int i = 1;
public void print() {
System.out.println("约吗");
}
}
}
class Demo {
public static void main(String[] args) {
Outer outer = new Outer();
outer.show();
}
}
class Outer {
private class Inner { //
int i = 1;
public void print() {
System.out.println("约吗");
}
}
public void show() {
Inner inner = new Inner();
System.out.println(inner.i);
inner.print();
}
}
局部内部类
定义在方法中的内部类
class Outer {
public void print() {
class Inner { //局部内部类
}
}
}
局部内部类怎么使用? ```java class Demo { public static void main(String[] args) {
Outer outer = new Outer();
outer.print();
} }
class Outer { public void print() { class Inner { int i = 2; public void show() { System.out.println(“滚犊子”); } }
Inner inner = new Inner();
System.out.println(inner.i);
inner.show();
}
}
<a name="U1iVa"></a>
# 🚴 匿名内部类
> 没有名字的局部内部类,也叫做匿名子类对象
<a name="XoXVr"></a>
## 匿名内部类的定义格式
```java
new 类名/接口名() {
//重写的方法
//自定义的方法
};
new Person() {
};
我们什么时候可以使用匿名子类对象?
当一个方法的形参是接口或者抽象类的时候,我们就可以选择使用匿名子类对象
interface Inter {
public abstract void print();
}
class Demo {
public static void main(String[] args) {
show(new Inter() {
public void print() {
System.out.println("真棒");
}
});
}
public static void show(Inter inter) {//Inter inter = new Inter() {
// public void print() {
// System.out.println("约吗");
// }
//};
inter.print();
}
}
面试题?
public class Demo01 {
public static void main(String[] args) {
new Fu() {
//方法的重写
public void show(Inter inter) {
inter.print();
}
}.show(new Inter() {
//方法的重写
public void print() {
System.out.println("约吗");
}
});
}
}
abstract class Fu {
public abstract void show(Inter inter);
}
interface Inter {
public abstract void print();
}
public class Demo02 {
public static void main(String[] args) {
Tool.getInstance().show();//在控制台上打印出一句话
}
}
interface Inter {
public abstract void show();
}
class Tool {
public static Inter getInstance() {
return new Inter() {
public void show() {
System.out.println("约吗");
}
};
}
}
五子棋
落子功能
1.棋子如果做出来的,怎么能够实现恰好放到交叉点上
a.落在交叉点上
b.鼠标点哪个交叉点,棋子就落在哪个点上面
2.如何做棋子,放到棋盘上
任务:
1.做到黑白交替
2.在同一位置不能被覆盖
1.Object类
Object类是所有类的直接或者间接的超类
public boolean equals(Object obj):指示其他某个对象是否与此对象“相等”。
一般我们使用equals是用来比较两个对象是否相同(不是地址值的相同,是两个对象的属性是否完全一致)
==:
==如果两边是基本数据类型数据,比较的就是数值的大小
==如果两边是引用数据类型数据,比较的就是地址值
public String toString():返回该对象的字符串表示。
注意:当我们在输出语句中打印一个对象的时候,会默认调用该对象toString()方法
2.五子棋
判断胜负
重新开局
退出
保存棋谱
打谱(复盘)