第一章 接口
1 接口理解
- 引用数据类型
- 特殊的抽象类
- 接口为功能的集合,一般为抽象功能的集合
- class定义类,interface定义接口
- 类只能单继承,接口多实现
- 继承与实现非常像
子类继承父类,有权直接使用父类的成员,可以不重写直接使用
实现类实现一个接口,拥有了接口中的功能,但是都为抽象功能,需要实现类自己重写,侧重点关注的重写 - 定义开发规范,面向接口编程
- 实现解耦,降低耦合度
2 语法
-
jdk1.7及之前
公共的静态的常量 : public static final 任意省略
公共的抽象的方法 : public abstract 任意省略 -
jdk1.8及之后
-
静态方法 : 被static关键字修饰的方法
通过接口名调用 -
默认方法 : 被default关键字修饰的方法
通过实现类对象调用 -
类的多态
-
接口多态:只能调用接口中存在的内容,对实现类新增内容不可见,如果实现类中存在重写方法调用重写后的方法
3 使用
- 接口不能实例化
- 需要通过实现类进行实现 implements
- 使用: 通过具体的实现类对象调用
具体实现类 : 重写所有的抽象方法 + 按需新增
抽象实现类 : 按需重写 + 按需新增
需要具体的子类继承,重写抽象方法 - 接口可以多实现,类只能单继承
- 一个类先继承父类,后实现接口
- 类与接口之间 : 只能类实现接口,多实现的关系
- 接口与接口之间 : 只能继承不能实现, 一个接口可以多继承其他接口
4 实例
4.1 jdk1.7及之前
public class Class001_Interface {
public static void main(String[] args) {
System.out.println(MyInterface.PI);
//MyInterface.PI = 100;
//实现类对象
Impl im = new Impl();
im.test1();
}
}
//接口
interface MyInterface{
//公共的静态的常量
double PI = 3.14;
//公共的抽象的方法
void test1();
void test2();
}
//具体实现类
class Impl extends Object implements MyInterface,D{
@Override
public void test1() {
}
@Override
public void test2() {
}
@Override
public void a() {
}
@Override
public void b() {
}
@Override
public void c() {
}
}
//抽象实现类
abstract class Impl2 implements MyInterface{
@Override
public void test1() {
}
//public abstract void test2();
}
interface A{
void a();
}
interface B{
void b();
}
interface C{
void c();
}
interface D extends A,B,C{}
4.2 jdk1.8及之后
public class Class002_Interface {
public static void main(String[] args) {
//静态方法
MyInterface2.testStatic();
//实现类对象调用
new Impl3().testDefault();
//接口多态 : 只能调用接口中存在的内容,对实现类新增内容不可见,如果实现类中存在重写方法调用重写后的方法
MyInterface2 i = new Impl3();
}
}
interface MyInterface2{
//静态方法
public static void testStatic(){
System.out.println("静态方法");
}
//默认方法
public default void testDefault(){
System.out.println("默认方法");
}
}
//实现类
class Impl3 implements MyInterface2{
}
5 电脑使用外接设备
5.1 分析
- 电脑使用外接USB设备 :
涉及到了几种事物:
1)电脑
2)鼠标,键盘…
3)USB接口
5.2 代码
public class Class001_Computer {
public static void main(String[] args) {
Computer com = new Computer("外星人",30000.0);
Mouse mouse = new Mouse();
com.open();
com.useUSB(mouse);
com.close();
}
}
//USB
interface USB{
void start();
void end();
}
//鼠标
class Mouse implements USB{
@Override
public void start() {
System.out.println("开始使用鼠标");
}
@Override
public void end() {
System.out.println("结束使用鼠标");
}
}
//电脑
class Computer{
private String brand;
private double price;
public Computer() {
}
public Computer(String brand, double price) {
this.brand = brand;
this.price = price;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "Computer{" +
"brand='" + brand + '\'' +
", price=" + price +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Computer computer = (Computer) o;
return Double.compare(computer.price, price) == 0 &&
Objects.equals(brand, computer.brand);
}
//开机
public void open(){
System.out.println("开机");
}
//使用外接USB设备
public void useUSB(USB usb){ //参数 : 实现了USB接口的实现类对象都能传递-->USB设备
//USB usb = new Mouse(); 接口多态
usb.start();
usb.end();
}
//关机
public void close(){
System.out.println("关机");
}
}
第二章 内部类
1 内部类
了解
- 类中定义类
- 外部类 内部类
2 分类
成员内部类
私有内部类
静态内部类
局部内部类
匿名内部类 : 重点
3 成员内部类
3.1 理解
- 内部类定义在外部类的成员位置
- 具有类的特点,可以继承其他父类,实现其他接口,具有成员的特点,可以被成员修饰符修饰…
3.2 注意
- 成员内部类中不能定义静态内容,除了静态的常量
- 成员内部类中可以直接使用外部类的成员,包括私有的
- 外部类中可以通过成员内部类的对象调用成员内部类的成员
- 通过外部类对象去创建成员内部类的对象,通过成员内部类对象调用成员内部类的成员
3.3 代码
3.3.1 成员变量
public class Class001_Outer {
//成员 : 类中方法外
//成员变量
private int i = 1;
static int j = 2;
//成员内部类
class Inner{
//成员变量
int a = 100;
static final int b = 200;
//成员方法
public void testInner(){
System.out.println(a);
System.out.println(b);
System.out.println(i);
System.out.println(j);
}
}
//成员方法
public void outer(){
Inner in = new Inner();
System.out.println(in.a);
}
}
3.3.2 测试类,不同类测试
public class Class002_Test {
public static void main(String[] args) {
//测试使用成员内部类中的成员
Class001_Outer outer = new Class001_Outer();
Class001_Outer.Inner in = outer.new Inner();
in.testInner();
}
}
4 区分同名问题
4.1 区分同名问题
- 调用外部类成员变量 Class003_Outer.this.i
- 调用内部类成员变量i=2 this.i
- 调用局部变量i=3 i
4.2 代码
4.2.1 区分同名问题
//区分同名变量问题
public class Class003_Outer {
int i=1;
static int b=5;
class Inner{
int i=2;
public void inner(){
int i=3;
//调用外部类成员变量i=1
System.out.println(Class003_Outer.this.i);
//调用内部类成员变量i=2
System.out.println(this.i);
//调用局部变量i=3
System.out.println(i);
}
}
}
4.2.2 测试类代码,不同类测试
public class Class002_Test {
public static void main(String[] args) {
//测试区分同名问题
/* Class003_Outer.Inner in2 = new Class003_Outer().new Inner();
in2.inner();*/
}
}
5 私有内部类
5.1 注意
- 被private关键字修饰的成员内部类
- 私有内部类中可以直接使用外部类的成员,包括私有的
- 在外部类中通过私有内部类的对象调用私有内部类的成员,包括私有的
- 私有内部类只能在当前外部类中使用,其他类中无法使用
5.2 代码
5.2.1 同类测试
public class Class004_Outer {
private int i = 1;
private static int j = 2;
//私有内部类
private class Inner{
private int a = 100;
private static final int b = 200;
public void test(){
System.out.println("私有内部类的成员方法");
System.out.println(a);
System.out.println(b);
System.out.println(i);
System.out.println(j);
}
}
//外部类的成员方法
public void outer(){
Inner in = new Inner();
System.out.println(in.a);
in.test();
}
}
5.2.2 不同类测试
public class Class002_Test {
public static void main(String[] args) {
//测试私有内部类的使用 --> 无法使用
// new Class004_Outer().new Inner();
}
}
6 静态内部类
6.1 理解
- 静态内部类中可以定义静态内容
- 在静态内部类中可以直接使用外部类的静态内容,需要通过外部类对象使用外部类的成员
- 在外部类中可以通过静态内部类的类名调用静态内部类的静态内容,可以通过静态内部类的对象调用其成员内容
- 在其他类中可以通过外部类类名找到静态内部类,new 静态内部类对象访问其成员,通过静态内部类类名方法其静态内容
Class005_Outer.Inner in3 = new Class005_Outer.Inner();
6.2 代码
6.2.1 本类测试
public class Class005_Outer {
private int i = 1;
private static int j = 2;
//静态内部类
static class Inner{
int a = 100;
static int b = 200;
//成员方法
public void test(){
System.out.println(b);
System.out.println(a);
System.out.println(j);
System.out.println(new Class005_Outer().i);
}
//静态方法
public static void testStatic(){
Inner in = new Inner();
System.out.println(in.a);
System.out.println(b);
System.out.println(new Class005_Outer().i);
System.out.println(j);
}
}
//外部类的成员方法
public void outer(){
System.out.println(Inner.b);
Inner.testStatic();
new Inner().test();
}
}
6.2.2 不同类测试
public class Class002_Test {
public static void main(String[] args) {
//测试静态内部类的使用
/* Class005_Outer.Inner.testStatic();
Class005_Outer.Inner in3 = new Class005_Outer.Inner();
in3.test();*/
}
}
7 局部内部类
7.1 理解
定义在局部位置
- 局部内部类中可以定义成员内容,不可能定义静态内容除了静态的常量
- 只能在局部内部类所在的方法中通过对象访问成员
- 在局部内部类中可以使用所在方法中的局部变量,可以使用外部类的成员
- 如果在局部内部类中使用所在方法中的局部变量(参数),要求局部变量被final修饰,如果jdk1.8以上版本默认被final修饰
7.2 代码
public class Class006_Outer {
String str = "外部类str";
public void test(int i){
//局部
//int i = 1;
//局部内部类
class Inner{
int a = 100;
static final int b = 200;
public void testInner(){
System.out.println("局部内部类的成员方法");
System.out.println(i);
System.out.println(str);
}
}
//i = 6;
System.out.println(Inner.b);
Inner in = new Inner();
System.out.println(in.a);
}
}
8 匿名内部类
8.1 理解
-
匿名内部类 : ****
作用 : 简化实现类|子类,没有自己类本身作用的实现类|子类 -
匿名内部类对象 : 实现类|子类+创建对象
new Smoke(){ //实现类类体|抽象类的子类类体
@Override
public void smoking() {
System.out.println(“边吸烟边吐烟圈…”);
}
}
8.2 作用
8.2.1. 匿名内部类对象
- 匿名对象 :只能在当前位置使用一次
8.2.2 引用指向匿名内部类对象
- 接口多态 : 接口引用调用的为接口中定义的成员
8.2.3 匿名内部类对象作为方法的实参
8.3 代码
public class Class007_Outer {
public static void main(String[] args) {
//实现类对象
Demo demo = new Demo();
demo.smoking();
//匿名内部类对象
//1. 匿名对象 : 只能在当前位置使用一次
new Smoke(){ //实现类的类体 | 匿名内部类的类体
@Override
public void smoking() {
System.out.println("一边打游戏一边吸烟...");
}
}.smoking();
//2.引用指向匿名内部类对象
//接口多态 : 接口引用调用的为接口中定义的成员
Smoke s = new Smoke(){
@Override
public void smoking() {
System.out.println("一边上课一边抽烟");
}
};
s.smoking();
s.smoking();
s.smoking();
//3.匿名内部类对象作为方法的实参
test(new Smoke() {
@Override
public void smoking() {
System.out.println("xxxxxxxx");
}
});
}
public static void test(Smoke smoke){
smoke.smoking();
}
}
interface Smoke{
void smoking();
}
class Demo implements Smoke{
@Override
public void smoking() {
System.out.println("边吸烟边吐烟圈...");
}
}
第三章 lambda表达式
1作用
- 简化匿名内部类对象
2 前提
- 函数式接口
函数式接口 : 接口中只有一个必须被重写的抽象方法
强制检查是否为函数式接口 : @FunctionalInterface
3语法
()->{}
() : 接口中抽象方法的参数列表
-> : lambda符号|箭头函数
{} : 重写方法的方法体
- Lambda写法1 : ()->{}
- Lambda写法2 : 如果方法体语句只有一句,前后的{}可以省略
- Lambda写法3 : 如果方法存在参数,参数的类型可以省略
- Lambda写法4 : 如果参数只有一个,前后的()可以省略
- Lambda写法5 : 如果lambda体语句只有一句,并且为return语句,前后的{}与return关键字可以一起省略
4 代码
public class Class001_Lambda {
public static void main(String[] args) {
//匿名内部类
/*Swim s = new Swim(){
@Override
public void swimming() {
System.out.println("一边喝水一边游泳...");
}
};*/
//Lambda写法1 : ()->{}
/*Swim s = ()->{
System.out.println("一边换气一边游泳...");
};*/
//Lambda写法2 : 如果方法体语句只有一句,前后的{}可以省略
//Swim s = ()->System.out.println("一边嘻嘻笑一边游泳...");
//Lambda写法3 : 如果方法存在参数,参数的类型可以省略
// Swim s = (name,age)->System.out.println(name+"一边嘻嘻笑一边游泳...");
//Lambda写法4 : 如果参数只有一个,前后的()可以省略
//Swim s = name->System.out.println(name+"一边嘻嘻笑一边游泳...");
//Lambda写法5 : 如果lambda体语句只有一句,并且为return语句,前后的{}与return关键字可以一起省略
Swim s = age->age>18;
System.out.println(s.swimming(18));;
}
}
@FunctionalInterface
interface Swim{
boolean swimming(int age);
//void drinkWater();
}
interface Run{
void run();
}