一、接口
1.1接口的基本使用
- 概念:接口相当于特殊的抽象类,定义方式,组成部分与抽象类相似,使用interface关键字定义接口
- 特点
- 用
interface
来定义 - 只能有公开的静态常量 默认使用
public static final
修饰 - 只能有公开的抽象方法 默认使用了
public abstract
修饰 - 没有构造方法 不能创建对象
- 接口中没有构造器
- 接口可以继承接口,并且支持多继承
- 用
语法
//定义接口
public interface MyInterface {
//只能有公开的静态常量,默认使用public static final修饰
public static final int a=10;
//只能有公开的抽象方法,默认使用public abstract修饰
public abstract void show();//不能加方法体
}
//实现类实现接口
public class MyInterfaceImpl implements com.InterfDemo.MyInterface {
@Override
public void show() {
System.out.println("实现类实现了接口中的show方法");
}
}
//测试类
import com.InterfDemo.Impl.MyInterfaceImpl;
public class Test {
public static void main(String[] args) {
System.out.println(MyInterface.a);
MyInterfaceImpl myInterface = new MyInterfaceImpl();
myInterface.show();
}
}
1.2与抽象类的区别
相同点:
- 不能创建对象
- 可以编译成字节码文件 .class
- 可以作为引用类型
- 具备Object类中所有定义的方法
不同点:
- 接口的所有的属性都是公开静态常量,隐式的使用public static final 修饰
- 接口的所有的方法都是公开抽象方法,隐式使用public abstract修饰
- 没有静态方法 动态 静态代码块
二、微观接口
-
什么是接口:接口是一种能力和约定
-
接口的定义:代表某种能力
-
方法的定义:能力的具体要求
-
经验
- Java为单继承,当父类方法种类无法满足子类需求时,可实现接口扩充子类能力
- 接口支持多实现,可为类拓展多种能力
//创建一个父类
public class Animal {
public void eat(){}
public void sleep(){}
}
//创建功能接口run
public interface Running {
void run();
}
//创建功能接口Swimming
public interface Swimming {//能力 游泳
void swimming();
}
//狗类实现继承,实现多接口
public class Dog extends Animal implements Swimming,Running{
@Override
public void eat() {
System.out.println("eat");
}
@Override
public void sleep() {
System.out.println("sleep");
}
@Override
public void swimming() {
System.out.println("狗刨");
}
@Override
public void run() {
System.out.println("running");
}
}
//测试
public class Teat {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat();
dog.sleep();
dog.swimming();
dog.run();
System.out.println("++++++++++++++++++++++++++++++++++++++++++");
Fish fish = new Fish();
fish.eat();
fish.sleep();
fish.swimming();
}
}
三、接口规范
- 任何类在实现接口时,必须实现接口中的所有抽象方法,否则为抽象类
- 实现接口中的抽象方法,访问修饰符必须是public
- 接口也可以声明为引用并指向实现类对象
四、接口实现多态
- 不同的引用类型,只能调用自身类型所定义的方法
五、接口中常见关系
- 类与类
- 单继承
extends 父类名称
- 类与接口
- 实现 多实现
implement 接口名1,接口名2...
- 接口与接口
- 继承 多继承
extends 父接口1,父接口2...
六、常量接口
-
将多个常量表示状态和固定值,以静态常量的形式定义在接口中统一管理,提高代码可读性
-
//接口 public interface Constants { //表示状态 int ZAI_XIAN=100;// 在线 int YIN_SHEN=50;//隐身 int LI_XIAN=20;//离线 int MANG_LU=200;//忙碌 } //测试类 public class Test { public static void main(String[] args) { int num= new Scanner(System.in).nextInt(); switch (num){ case Constants.ZAI_XIAN: System.out.println("在线"); break; case Constants.LI_XIAN: System.out.println("离线"); break; case Constants.MANG_LU: System.out.println("忙碌"); break; case Constants.YIN_SHEN: System.out.println("隐身"); break; default: break; } } }
七、宏观接口
- 宏观概念:接口是一种标准、规范
//定义接口 ProductManager
public interface ProductManager {
//增加商品
boolean addProduct(Product product);
//删除商品
boolean deleteProduct(int id);
//修改商品
boolean updateProduct(Product product);
//查询商品
Product[] selectAll();
//商品详情
Product selectById(int id);
}
//定义商品类
public class Product {
private int id;
private String name;
private int num;
private double price;
private String info;
public Product() {
}
public Product(int id, String name, int num, double price, String info) {
this.id = id;
this.name = name;
this.num = num;
this.price = price;
this.info = info;
}
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;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
//ProductManagerImpl实现接口的类
import java.util.Arrays;
public class ProductManagerImpl implements ProductManager{
//定义商品数组保存所有商品
static Product[] products = new Product[5];
int size = 5;
static {
products[0] = new Product(1,"小米",123,12000.2,"为发烧而生");
products[1] = new Product(2,"小米",123,12222.2,"为发烧而生");
products[2] = new Product(3,"小米",123,12111.2,"为发烧而生");
products[3] = new Product(4,"小米",123,12333.2,"为发烧而生");
products[4] = new Product(5,"小米",123,12444.2,"为发烧而生");
}
//增加商品
@Override
public boolean addProduct(Product product) {
//判断商品是否存在
if (selectById(product.getId())!=null){//表示没有数据
return false;
}
//判断数组长度是否需要扩容
if (size== products.length){//表示数组满了需要扩容
products= Arrays.copyOf(products,products.length+5);
}
//添加到数组中
products[size++]=product;
return true;
}
//删除商品
@Override
public boolean deleteProduct(int id) {
//判断是否有该商品
if (selectById(id)==null){
return false;
}
//获取到id所在的下标位置
int index = -1;
for (int i = 0; i < size; i++) {
if(id==products[i].getId()){
index=i;
break;
}
}
//考虑数组元素刚好为5时进行扩容
if(size%5==0){
products= Arrays.copyOf(products,products.length+5);
}
//将从index位置开始,当前位置的只赋值成后面位置上的只
for (int i = index; i < size; i++) {
products[i]=products[i+1];
}
size--;
return true;
}
//修改商品
@Override
public boolean updateProduct(Product product) {
//判断是否存在
if (selectById(product.getId())==null){
return false;
}
//获取要修改值的下标
int index = -1;
for (int i = 0; i < size; i++) {
if(product.getId()==products[i].getId()){
index=i;
break;
}
}
//将下标位置上的商品覆盖修改
products[index]=product;
return true;
}
//查询全部
@Override
public Product[] selectAll() {
return products;
}
//通过id删除
@Override
public Product selectById(int id) {
//遍历数组
for (int i = 0; i < size; i++) {
if (id==products[i].getId()){
return products[i];
}
}
return null;
}
}
//测试类
public class Test {
public static void main(String[] args) {
ProductManagerImpl PM = new ProductManagerImpl();
// Product p1 = new Product(6, "Iphone14 pro Max", 1000000, 10000, "灵动岛");
// //增加商品
// if (PM.addProduct(p1)){
// System.out.println("增加成功");
// }else {
// System.out.println("增加失败");
// }
//
// //删除商品
//
// if (PM.deleteProduct(6)){
// System.out.println("删除成功");
// }else {
// System.out.println("删除失败");
// }
Product p2 = new Product(5, "小米999", 2999, 10000, "为发烧而生");
//修改商品
PM.updateProduct(p2);
//查询商品
Product[] products = PM.selectAll();
for (int i = 0; i <products.length ; i++) {
System.out.println(products[i].getId()+products[i].getName()+products[i].getPrice());
}
//获取单个商品的信息
Product product = PM.selectById(5);
System.out.println(product.getName());
}
}
八、什么是接口回调
先用接口的使用者,后用接口的实现者
就是通过接口来调用接口中的方法
九、接口的好处
- 程序的耦合度降低
- 更自然的使用多态
- 设计与实现完全分离
- 更容易搭建程序框架
- 更容易更换具体实现
二、内部类
2.1、内部类
2.1.1内部类的概念
- 在一个类中定义的类,称之为内部类(InnerClass),外面的类称之为外部类(OutClass)
- 内部类分类:
- 成员内部类
- 静态内部类
- 静态内部类不能访问外部的非静态成员
- 局部内部类
- 定义在外部类方法当中,作用范围创建对象范围仅限于当前方法
- 局部内部类可以访问外部的非静态成员,类中不能定义静态属性和方法
- 匿名内部类
- 特点:
- 匿名内部类就是一个对象
- 匿名内部类的父类通常情况下就是抽象类或者接口
- 语法:
new 父类(参数构造){}
- 特点:
- 内部类特点:
- 内部类可以访问外部类的私有成员,且不破坏封装性
- 内部类也会生成class文件,名为外部类名字$内部类名字.class
- 外部类特点:
- 一个java文件可以编写多个类,但是只能有一个使用public修饰,称之为主类,主类类名必须一致