方法
拥有功能性代码的代码块
将不同的功能性代码放在不同的方法中,给每个方法取个名字,直接调用;
修饰符 返回值类型 方法名(参数){…方法体,return 结果;}
- 无参无返回值
void :代表无返回值;
方法与方法之间不能嵌套
方法的执行只和调用顺序有关系
package alive.methods;
/**
* @Author zyj
* @Date 2024/08/19 19:30
* @Description
*/
public class Meth {
public static void main(String[] args) {
}
public static void say() {
System.out.println("hello");
}
}
- 无参有返回
返回值类型 必须和 结果类型一致
package alive.methods;
/**
* @Author zyj
* @Date 2024/08/19 19:30
* @Description
*/
public class Meth {
public static void main(String[] args) {
int result = sum();
System.out.println(result);
}
public static int sum() {
return 1 + 1;
}
}
- 有参无返回
参数类型与传入类型的一致,且必填
package alive.methods;
/**
* @Author zyj
* @Date 2024/08/19 19:30
* @Description
*/
public class Meth {
public static void main(String[] args) {
action(1, 3);
}
public static void action(int a, int b) {
System.out.println(a + b);
}
}
- 有参有返回
package alive.methods;
/**
* @Author zyj
* @Date 2024/08/19 19:30
* @Description
*/
public class Meth {
public static void main(String[] args) {
int result = getSum(1, 2);
System.out.println(result);
}
public static int getSum(int a, int b) {
return a + b;
}
}
- 数组作为参数
传递的是地址值,形参和实参指向同一地址值
package alive.methods;
/**
* @Author zyj
* @Date 2024/08/19 19:30
* @Description
*/
public class Meth {
public static void main(String[] args) {
int[] arr = {1, 2, 3};
setArr(arr);
// 结果为100
System.out.println(arr[0]);
}
public static void setArr(int[] arr) {
arr[0] = 100;
}
}
方法重载
方法名相同,参数列表不同的方法
- 参数个数不同
- 参数类型不同
- 参数顺序不同
和参数名称无关
和返回值无关(有无返回值都属于同一个方法,不是重载)
package alive.methods;
/**
* @Author zyj
* @Date 2024/08/19 20:16
* @Description
*/
public class OverLoad {
public static void main(String[] args) {
sum(1, 2);
sum(1, 2, 3);
sum(1, 2, 3, 4);
}
// 两个整数相加
public static void sum(int a, int b) {
System.out.println(a + b);
}
// 三个整数相加
public static void sum(int a, int b, int c) {
System.out.println(a + b + c);
}
// 四个正式相加
public static void sum(int a, int b, int c, int d) {
System.out.println(a + b + c + d);
}
}
类和对象
面向对象
面向过程:自己的事情自己干,代表语言C
洗衣服 按照步骤去做
面向对象
说出需求,有人去帮你干
类(实体类)class
测试类:带 main 方法的类,主要运行代码
实体类:是一类事物的抽象表达形式
组成部分
属性(成员变量)
行为(成员方法)
package alive.c_class;
/**
* @Author zyj
* @Date 2024/08/19 20:42
* @Description
*/
public class Person {
String name = "";
int age = 18;
public void say() {
System.out.println("你好呀");
}
public void eat() {
System.out.println("吃东西");
}
}
对象
概述:一类事物的具体体现
使用:
- 导包:
import
报名.类名
如果两个类在同一个包下,想要使用对方的成员不需要导包
如果两个类不在同一个包下,使用就需要导包
特殊包:java.lang->
使用lang包下的类不需要导包
创建对象:
类名 对象名 = new 类名()
Person p =new
Person();
调用成员(成员变量,成员方法)
对象名.
成员变量名 = 值;
对象名.
方法名()
匿名对象
只有= 左边的值
new Person()
内存图
封装
将细节隐藏起来,并提供接口供外部调用
- private 权限修饰符,只能在本类中使用
- this:代表的就是当前对象,this
.
成员变量
package alive.c_class;
/**
* @Author zyj
* @Date 2024/08/19 20:42
* @Description
*/
public class Person {
private String name = "";
private int age = 18;
public void say() {
System.out.println("你好呀");
}
public void eat() {
System.out.println("吃东西");
}
public void setName(String nane) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setAge(int age) {
if (age > 0) this.age = age;
}
public int getAge() {
return this.age;
}
}
构造方法、
方法名和类名一致并且能够初始化对象的方法
格式:public 类名(){…}
- 无参构造:虚拟机默认会创建此方法
public Person() {
System.out.println("无参构造");
}
- 有参构造:JVM 不会自动提供有参构造,但是将有参构造写出来,JVM 不会再提供
public Person(String name, int age) {
System.out.println("带参构造");
this.name = name;
this.age = age;
}
JavaBean
是java编写类的一种标准规范。
符合JavaBean的类:
- 类必须是具体的(非抽象abstract)和公共的,public class 类名
- 并且具有无参构造方法,有参构造方法
- 成员变量私有化,并提供用来操作成员变量的set和get方法
package alive.c_class;
/**
* @Author zyj
* @Date 2024/08/21 16:21
* @Description javaBean
*/
public class Phone {
private String brand;
private String color;
public Phone(String brand, String color) {
this.brand = brand;
this.color = color;
}
public Phone() {
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
static
static 是个静态关键字;
使用:
- 修饰一个成员变量
- 修饰一个成员方法
调用
类名.
属性名
静态成员的特点:
- 静态成员属于类成员,不属于对象成员(非静态的成员)
- 静态成员会随着类的加载而加载
- 静态成员优先于非静态成员存在于内存中
- 凡是根据静态成员所在的类创建出来的对象都可以共享这个静态成员;
package alive.c_class;
/**
* @Author zyj
* @Date 2024/08/21 17:37
* @Description
*/
public class Student {
private String name;
private int age;
public static String CLASS_ROOM = "1001";
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package alive.methods;
import alive.c_class.Student;
/**
* @Author zyj
* @Date 2024/08/21 14:36
* @Description
*/
public class Test {
public static void main(String[] args) {
Student s1 = new Student("alex", 18);
System.out.println(s1.getAge());
System.out.println(s1.getName());
System.out.println(Student.CLASS_ROOM);
Student s2 = new Student("Jack", 20);
System.out.println(s2.getAge());
System.out.println(s2.getName());
System.out.println(Student.CLASS_ROOM);
System.out.println("修改CLASS_ROOM:1002");
Student.CLASS_ROOM = "1002";
System.out.println(Student.CLASS_ROOM);
}
}
内存
static 访问特点
- 在静态成员访问非静态成员
不能直接访问
使用new
关键字创建对象
- 在非静态方法中访问静态成员
同类中:可以直接调用,也可
类名
调用
不同类中:类名
调用
- 在静态方法中访问静态成员
同类中:可以直接调用,也可
类名
调用
不同类中:类名
调用
- 在非静态成员方法中访问非静态成员
同类:直接调用
new
调用
不同类:new
调用
static 使用场景
静态成员会随着类的加载而加载,如果将所有的成员都变成静态的,那么类的加载,静态成员的进入内存中,会大量占用内存空间。
何时定义为静态成员:
一般情况下,抽取工具类的时候,可以将根据类的成员都定义成静态类;
代码反复出现,功能一致,这类代码就可抽取为静态类;
package alive.s_static;
/**
* @Author zyj
* @Date 2024/08/23 17:22
* @Description 操作数组的工具类
*/
public class ArrayUtil {
/**
* 工具类中的成员都是静态的,可以用类名直接调用,不需要new对象
* 使用private修饰构造方法
*/
private ArrayUtil() {
}
;
public static int getMax(int[] arr) {
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (max < arr[i]) {
max = arr[i];
}
}
return max;
}
}
package alive.s_static;
/**
* @Author zyj
* @Date 2024/08/23 20:44
* @Description
*/
public class Test {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4};
System.out.println("最大值是:" + ArrayUtil.getMax(arr));
}
}
可变参数
只明确参数的类型,不知道其个数
格式:
(数据类型… 形参名)
package alive.v_var;
/**
* @Author zyj
* @Date 2024/08/23 20:49
* @Description
*/
public class Test {
public static void main(String[] args) {
sum(1, 2, 3, 4, 5, 6, 7, 8);
}
public static void sum(int... arr) {
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
System.out.println("sum:" + sum);
}
}
递归
方法内部自己调用自己
直接递归
间接递归
注意:递归需要有出口,容易造成“栈内存溢出”
package alive.recur;
/**
* @Author zyj
* @Date 2024/08/23 21:08
* @Description
*/
public class Recur {
public static void main(String[] args) {
print(5);
}
;
public static void print(int n) {
if (n <= 0) return;
System.out.println(n);
n--;
print(n);
}
}
数组常见算法
翻转
继承
继承
我们定义多个类,发现这些类中有很多重复的代码,我们就定义了一个父类,将相同的代码抽取出来放到父类中,其他类直接继承这个父类,就可以直接使用父类中的内容
使用关键字
extends
子类extends
父类
注意:
- 子类可以继承父类中私有和非私有成员,但是不能使用父类中私有成员。
- 构造方法不能被继承
成员变量的访问
= 左边的是谁,先调用谁中的成员,子类没有,找父类
成员方法的特点:看new
是谁,先调用谁的方法
方法的重写
概述:子类中有一个和父类方法名以及参数列表相同的方法
前提:继承
访问:看new
的是谁就先调用,如果是子类重写的方法,子类没有就调用父类
@Override
注意事项
- 子类重写父类方法之后,权限必须保证比大于等于父类权限(权限指的是访问权限)
public
>protected
>默认
>private
私有方法不能被重写,构造方法不能被重写,静态方法不能被重写
子类重写父类方法之后,返回值类型应该是父类方法返回值类型的子类类型
继承中的构造方法的特点
new
子类对象时,会先初始化父类的构造方法
每个构造方法默认JVM自动提供一个super
- 子类无参构造,默认Jvm 自动增加
super
构造父类的无参构造方法- 子类有参构造,也是默认调用的父类的
super
无参构造- 需要子类手动增加父类的 有参构造;
package alive.e_extends;
/**
* @Author zyj
* @Date 2024/08/23 22:47
* @Description
*/
public class Test {
public static void main(String[] args) {
BaseExt baseExt = new BaseExt("xiaomi", 18, "alex");
}
}
package alive.e_extends;
/**
* @Author zyj
* @Date 2024/08/24 11:02
* @Description
*/
public class BaseExt extends Base {
public BaseExt(String brand, int age, String name) {
super(name, age);
this.brand = brand;
System.out.println("baseExt 有参构造");
}
public BaseExt() {
System.out.println("baseExt 构造方法");
}
private String brand;
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
}
super
代表父类的引用
调用父类中的成员
使用:
- 调用父类构造方法
->
在子类的构造方法中写,且必须写在首行
;
super()
调用父类的构造方法
子类中,调用父类的方法和成员变量
super.父类
this
代表当前对象;
作用:
- 区分重名的成员变量和局部变量;
- 调用当前对象中的成员
作用:
- 调用当前对象的构造
this()
:调用当前对象的无参构造
this(有参)
:调用当前对象的有参构造- 调用当前对象的成员变量:
this.成员变量名
- 调用当前对象的成员方法
this.成员方法名
this
和super
在构造函数中都必须放在第一行,所以二者不能同时出现
继承的特点
- 继承只能是单继承
- 继承支持多层继承
- 一个父类可以用多个子类
- 构造方法不能被继承,也不能被重写
- 私有方法不可以继承,不能被重写
- 静态方法可以继承,但是不能被重写
抽象
将公有的方法抽取出来,形成父类,但是抽取出来的方法没有具体实现,此时该方法不用方法体,没有方法体可以抽象成抽象方法
抽象方法所在的类必须是抽象类
abstract
关键字修饰
定义抽象方法
修饰符abstract
返回值类型 方法名(参数);
抽象类:
public abstract class 类名{}
抽象方法所在的类一定是抽象类
抽象类中不一定有抽象方法
子类继承抽象父类时,需要重写父类中所有的抽象方法
抽象类不能实例化对象,只能通过实例化子类实现的抽象方法
可以将抽象类看成一类事物的标准,要求只要是属于这一类的,都必须拥有抽象类的方法,必须实现抽象类中所有的方法,实现
->
重写方法
package alive.a_abs;
/**
* @Author zyj
* @Date 2024/08/24 12:37
* @Description
*/
public abstract class Animal {
public abstract void eat();
public abstract void say();
}
package alive.a_abs;
/**
* @Author zyj
* @Date 2024/08/24 12:37
* @Description
*/
public class Dog extends Animal {
@Override
public void eat() {
System.out.println("dog eat");
}
@Override
public void say() {
System.out.println("wang wang ~~~~");
}
}
抽象类中可以有成员变量,构造方法,成员方法
案列
package alive.b_abstract;
/**
* @Author zyj
* @Date 2024/08/24 13:04
* @Description 抽象类 员工
*/
public abstract class Employee {
// 员工id
private int id;
// 员工名称
private String name;
// 抽象类
public abstract void work();
public Employee() {
}
public Employee(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package alive.b_abstract;
/**
* @Author zyj
* @Date 2024/08/24 13:09
* @Description 开发实现类
*/
public class Developer extends Employee {
public Developer() {
}
public Developer(int id, String name) {
super(id, name);
}
@Override
public void work() {
System.out.println("软件研发工程师");
}
}
package alive.b_abstract;
/**
* @Author zyj
* @Date 2024/08/24 13:12
* @Description Android 实现类
*/
public class Android extends Employee {
public Android() {
}
public Android(int id, String name) {
super(id, name);
}
@Override
public void work() {
System.out.println("Android开发");
}
}
package alive.b_abstract;
/**
* @Author zyj
* @Date 2024/08/24 13:10
* @Description
*/
public class Test {
public static void main(String[] args) {
Developer developer = new Developer(1001, "alex");
developer.work();
Android android = new Android(1002, "Jack");
android.work();
}
}
接口
是一种引用数据类型,是一种标准和规则
关键字:interface
public interface 接口名{}
implements
实现类 implement 接口名
使用
- 实现类实现接口中的方法;
- 重写接口中的抽象方法
- 创建实现类对象(接口不能直接
new
对象)- 调用重写的方法
package alive.f_interface;
/**
* @Author zyj
* @Date 2024/08/24 13:33
* @Description USB接口
*/
public interface USB {
public abstract void open();
public abstract void closed();
}
package alive.f_interface;
/**
* @Author zyj
* @Date 2024/08/24 13:35
* @Description
*/
public class Mouse implements USB {
@Override
public void open() {
System.out.println("鼠标打开");
}
@Override
public void closed() {
System.out.println("鼠标关闭");
}
}
接口中的成员
抽象方法
- 定义实现类,实现接口
- 重写抽象方法
- 创建实现类对象,调用重写的方法
默认方法
格式:
public default 返回值类型 方法名(形参){方法体 return 结果}
使用:
- 定义实现类,实现接口
- 默认方法可重写,可不重写
- 创建实现类对象,调用默认方法
package alive.f_interface;
/**
* @Author zyj
* @Date 2024/08/24 13:33
* @Description USB接口
*/
public interface USB {
public abstract void open();
public abstract void closed();
public default void def() {
System.out.println("接口中的默认方法");
}
}
package alive.f_interface;
/**
* @Author zyj
* @Date 2024/08/24 13:35
* @Description
*/
public class Mouse implements USB {
@Override
public void open() {
System.out.println("鼠标打开");
}
@Override
public void closed() {
System.out.println("鼠标关闭");
}
@Override
public void def() {
USB.super.def();
System.out.println("实现类的重写");
}
}
静态方法
格式
public static 返回值类型 方法名(形参){方法体,return 结果}
接口特点
- 接口可以多继承
package alive.f_interface;
/**
* @Author sorpei
* @Date 2024/08/24 13:59
* @Description
*/
public interface C extends A, B {
}
- 接口可以多实现
package alive.f_interface;
/**
* @Author zyj
* @Date 2024/08/24 14:00
* @Description
*/
public class D implements A, B, C {
}
- 一个子类可以继承一个父类的同时实现一个或者多个接口
package alive.f_interface;
/**
* @Author zyj
* @Date 2024/08/24 14:04
* @Description
*/
public class E extends D implements A, B, C {
}
注意:
继承、实现接口,只要父类中或者接口中的抽象方法,子类或者实现类都要重写
当一个类实现多个类,如果接口中的抽象方法有重名且参数一致的,都需要重写
package alive.f_interface;
/**
* @Author zyj
* @Date 2024/08/24 14:00
* @Description
*/
public class D implements A, B, C {
@Override
public void met() {
}
@Override
public void met(int i) {
}
}
当一个类实现多个接口时,如果默认方法有重名的,且参数一致的,必须重写一次默认方法
package alive.f_interface;
/**
* @Author zyj
* @Date 2024/08/24 13:59
* @Description
*/
public interface A {
public abstract void met();
public default void def() {
System.out.println("A的默认方法");
}
}
package alive.f_interface;
/**
* @Author zyj
* @Date 2024/08/24 13:59
* @Description
*/
public interface B {
public abstract void met(int i);
public default void def() {
System.out.println("B的默认方法");
}
}
接口和抽象类的区别
- 相同点
都位于继承体系的顶端,用于被其他类实现或者继承
都不能new
都包含抽象方法,其子类或者实现类都必须重写这些抽象方法
- 不同点:
抽象类:一般作为父类使用,可以用成员变量,构造方法,成员方法,抽象方法等;
接口:
- 成员单一,一般抽取接口,抽取的都是方法,视为功能的大集合
- 类不能多继承,但是接口可以
多态
前提:
- 必须有子父类继承或者接口实现关系
- 必须有方法的重写(没有重写,多态没有意义),多态核心就是重写方法
new
对象:父类应用指向子类对象
Fu fu =new
zi():大类型接受了一个小类型的数据double
b = 10;
注意:多态类 下不能直接调用子类特有的功能
package alive.g_polymorphic;
/**
* @Author zyj
* @Date 2024/08/24 14:37
* @Description
*/
public abstract class Animal {
public abstract void action();
}
package alive.g_polymorphic;
/**
* @Author zyj
* @Date 2024/08/24 14:38
* @Description
*/
public class Dog extends Animal {
@Override
public void action() {
System.out.println("守卫");
}
public void say() {
System.out.println("旺旺");
}
}
package alive.g_polymorphic;
/**
* @Author zyj
* @Date 2024/08/24 14:39
* @Description
*/
public class Cat extends Animal {
@Override
public void action() {
System.out.println("抓老鼠");
}
public void say() {
System.out.println("喵喵");
}
}
package alive.g_polymorphic;
/**
* @Author zyj
* @Date 2024/08/24 14:39
* @Description
*/
public class Test {
public static void main(String[] args) {
Dog dog = new Dog();
dog.action();
dog.say();
Cat cat = new Cat();
cat.action();
cat.say();
// 多态
Animal d = new Dog();
d.action();
// 报错,之类特有的方法
// d.say();
Animal c = new Cat();
c.action();
// 报错,子类特有的
// c.say();
}
}
多态成员访问特点
package alive.g_polymorphic;
/**
* @Author zyj
* @Date 2024/08/25 19:58
* @Description
*/
public abstract class Animal {
String name = "animal";
public abstract void action();
}
package alive.g_polymorphic;
/**
* @Author zyj
* @Date 2024/08/25 19:59
* @Description
*/
public class Dog extends Animal {
String name = "dog";
@Override
public void action() {
System.out.println("dog action");
}
}
package alive.g_polymorphic;
/**
* @Author zyj
* @Date 2024/08/25 20:00
* @Description
*/
public class Test {
public static void main(String[] args) {
Animal dog = new Dog();
dog.action();
// animal
System.out.println(dog.name);
}
}
= 左边是谁,先调用谁的成员变量
打印的是Animal 类中的name
成员方法看new
的是谁,先找的子类中的 action
多态的特点
原始创建:既能调用重写的,也能调用继承的,也能调用自己的,
多态:只能调用重写的,不能调用子类特有的成员
package alive.g_polymorphic;
/**
* @Author zyj
* @Date 2024/08/25 20:00
* @Description
*/
public class Test {
public static void main(String[] args) {
doAction(new Dog());
doAction(new Cat());
}
public static void doAction(Animal animal) {
animal.action();
}
}
多态的优点:我这个例子中,这个方法的形参是 父类的类型,所有我传参的时候只要传入
new
的子类就可以调用其实现的方法
多态转型
Animal animal = new Dog();
Dog dog = (Dog)animal;
ClassCastException
package alive.g_polymorphic;
/**
* @Author zyj
* @Date 2024/08/25 20:00
* @Description
*/
public class Test {
public static void main(String[] args) {
Animal dog = new Dog();
Animal cat = new Cat();
doAction(cat);
}
public static void doAction(Animal animal) {
animal.action();
Dog dog = (Dog) animal;
System.out.println(dog.name);
}
}
doAction
形参是Animal
,被向下转型为Dog
,但是实际传入的是Cat
就会报错;
Dog dog = (Dog)cat
强行将Cat 转成Dog
package alive.g_polymorphic;
/**
* @Author zyj
* @Date 2024/08/25 20:00
* @Description
*/
public class Test {
public static void main(String[] args) {
Animal dog = new Dog();
Animal cat = new Cat();
doAction(dog);
doAction(cat);
}
public static void doAction(Animal animal) {
if (animal instanceof Dog) {
Dog ani = (Dog) animal;
System.out.println(ani.name);
} else if (animal instanceof Cat) {
Cat ani = (Cat) animal;
System.out.println(ani.name);
}
}
}
权限修饰符
在Java中提供了四种访问修饰符,使用不同的访问权限修饰符时,被访问的内容会有不同的访问权限
- public-公共的,最高权限,被修饰的成员,在哪里都能被访问
- protected-受保护的
- default-默认的 注意 不写权限修饰符就是默认权限,且不能将default写出来
- private-私有的,只能在自己的类中访问
·— public protected default private 同类 Y Y Y Y 同包不同类 Y Y Y N 不同包子父类 Y Y N N 不同包非子父类 Y N N N 属性:
private
-封装
成员方法:public
-调用
构造public
new
对象
final
- 修饰类
被修饰的类不能被继承 - 修饰方法
修饰符final
返回值类型 方法名(形参)
被修饰的方法不能被重写
final 和 abstract 不能同时使用,抽象类方法必须要被重写 - 修饰局部变量
final
数据类型 变量名 = 值
被修饰的变量不能被二次赋值 - 修饰对象
final
数据类型 对象名 = new 对象()
不能二次赋值,需要手动赋值
代码块
- 构造代码块
{
}
执行特点:优先于构造方法执行,每
new
一次都会执行一次
- 静态代码块
static {
...代码块
}
执行特点: 静态代码块优先于构造代码块执行,且只执行一次
使用场景:如果想要一些数据最先初始化,而且只要初始化一次
内部类
在Java中,可以将一个类定义在另一个类中或者一个方法里面,这样的类称为内部类。
静态成员内部类
package alive.h_class;
/**
* @Author zyj
* @Date 2024/08/26 17:16
* @Description
*/
public class A {
static class B {
}
}
package alive.h_class;
/**
* @Author zyj
* @Date 2024/08/26 17:37
* @Description
*/
public class Test {
public static void main(String[] args) {
A.B b = new A.B();
System.out.println(b.name);
}
}
注意:
- 内部类可以定义属性,方法,构造等
- 静态内部类可以被
final
或者abstract
修饰
final
修饰之后,不能被继承;
abstract
修饰之后,不能new
- 静态成员内部类不能调用外部的非静态成员
- 内部类可以被四种权限修饰符修饰
使用:
外部类.内部类 变量名 = new 外部类.内部类
非静态成员内部类
package alive.h_class;
/**
* @Author zyj
* @Date 2024/08/26 17:37
* @Description
*/
public class Test {
public static void main(String[] args) {
A.B b = new A().new B();
System.out.println(b.name);
}
}
外部类的成员变量和内部类的成员变量以及内部类的局部变量重名区分?
package alive.h_class;
/**
* @Author zyj
* @Date 2024/08/26 17:16
* @Description
*/
public class A {
String name = "A-name";
int age;
class B {
public B() {
System.out.println("B-construct");
}
int age;
String name = "B-name";
public void display() {
System.out.println(this.name);
System.out.println(A.this.name);
}
}
}
局部内部类
可以定义在代码块中
package alive.h_class;
/**
* @Author zyj
* @Date 2024/08/26 17:16
* @Description
*/
public class A {
public void action() {
class B {
public B() {
System.out.println("B-construct");
}
public void action() {
System.out.println("B-action");
}
}
new B().action();
}
}
package alive.h_class;
/**
* @Author zyj
* @Date 2024/08/26 17:37
* @Description
*/
public class Test {
public static void main(String[] args) {
A a = new A();
a.action();
}
}
接口类型作为方法的参数传递和返回
package alive.i_interface;
/**
* @Author sorpei
* @Date 2024/08/28 10:44
* @Description
*/
public interface USB {
public abstract void open();
}
package alive.i_interface;
/**
* @Author zyj
* @Date 2024/08/28 10:45
* @Description
*/
public class Mouse implements USB {
@Override
public void open() {
System.out.println("open USB");
}
}
package alive.i_interface;
/**
* @Author zyj
* @Date 2024/08/28 10:47
* @Description
*/
public class Test {
public static void main(String[] args) {
Mouse mouse = new Mouse();
start(mouse);
USB usb = getDevice();
usb.open();
}
public static void start(USB usb) {
usb.open();
}
public static USB getDevice() {
return new Mouse();
}
}
抽象类作为方法的参数和返回值
package alive.i_interface;
/**
* @Author zyj
* @Date 2024/08/28 14:34
* @Description 动物抽象类
*/
public abstract class Animal {
public abstract void voice();
}
package alive.i_interface;
/**
* @Author zyj
* @Date 2024/08/28 14:35
* @Description
*/
public class Dog extends Animal {
@Override
public void voice() {
System.out.println("wang wang ~~~");
}
}
package alive.i_interface;
/**
* @Author zyj
* @Date 2024/08/28 10:47
* @Description
*/
public class Test {
public static void main(String[] args) {
action(new Dog());
Animal animal = getAnimal();
animal.voice();
}
public static void action(Animal animal) {
animal.voice();
}
public static Animal getAnimal() {
return new Dog();
}
}
普通类作为方法的参数和返回值
…
局部内部类实际操作
package alive.i_interface;
/**
* @Author zyj
* @Date 2024/08/28 10:47
* @Description
*/
public class Test {
public static void main(String[] args) {
USB usb = getUSB();
usb.open();
}
public static USB getUSB() {
class Mouse implements USB {
@Override
public void open() {
System.out.println("open - mouse");
}
}
return new Mouse();
}
}
匿名内部类(重点)
所谓的匿名内部类,可以理解没有显式声明出来的类
我们如果想要实现接口,简单使用一次抽象方法
- 创建实现类
- 重写方法
- 创建实现类对象
- 调用方法
package alive.j_class;
/**
* @Author zyj
* @Date 2024/08/28 15:16
* @Description
*/
public class Test {
public static void main(String[] args) {
new USB() {
@Override
public void open() {
System.out.println("open - main");
}
}.open();
USB usb = new USB() {
@Override
public void open() {
System.out.println("usb - opn ");
}
};
usb.open();
}
}
使用:
- 当简单调用一次接口中的方法,我们就可以使用匿名内部类;
- 将一种格式代表实现类对象或者子类对象来看待
- 匿名内部类会编译生成
开发中的使用
package alive.j_class;
/**
* @Author zyj
* @Date 2024/08/28 15:16
* @Description
*/
public class Test {
public static void main(String[] args) {
useUSB(new USB() {
@Override
public void open() {
System.out.println("打开USB");
}
});
USB device = getDevice();
device.open();
}
public static void useUSB(USB usb) {
usb.open();
}
public static USB getDevice() {
return new USB() {
@Override
public void open() {
System.out.println("打开了");
}
};
}
}