一、接口
1、概念
抽象类
abstract class A {
show();
add();
}
abstract class B {
fly();
run();
}
class Robot extends A{
}
public interface MyInterface {
public abstract void method(); // 接口中的方法定义
}
重点:抽象类是必须要被子类继承实现的。如果一个类既想实现A 中的方法又想实现B中的方法是无法完成的。
但是java类是单继承多实现的。
接口就是用来定义规则的,接口是为了拓展java单继承的缺陷产生的。
2、语法
属性
- 接口中的属性,默认都是静态常量,访问权限都是public。
- 方法
* - 接口中的方法,默认都是抽象方法,访问权限都是public。
package com.qfedu.day07;
/**
* @Author laoyan
* @Description TODO
* @Date 2022/3/9 9:59
* @Version 1.0
*
*
* 接口中可以定义:
*
* - 属性
* - 接口中的属性,默认都是静态常量,访问权限都是public。
* - 方法
* - 接口中的方法,默认都是抽象方法,访问权限都是public。
*
*/
public interface MyInterface {
/**
* 接口中只有两样东西
* 1、常量
* 2、抽象方法
*/
int a = 10;
void show();
}
3、接口和抽象类的异同
相同点:
1、都有抽象方法
2、都不能实例化 不能new 接口
3、都可以声明引用
Calendar c = Calendar.getInstance();
Animal a = new Dog();
Flying 接口
Flying fly = new Flying();// 错误
Flying fly = new Plane();
4、抽象类和接口都有Object的所有方法
5、抽象类和接口都有与之对应的class文件 Flying.java --> Flying.class
不同点:
1、抽象类中可以有普通方法,接口中没有
2、抽象类中可以有普通变量,接口中全部是常量
3、抽象类也是类,可以有构造方法以及代码块。接口没有这些。
4、接口如何实现呢?
public interface Flying {
void fly();
}
再写实现:
public class Dog implements Flying{
//alt + enter
@Override
public void fly() {
System.out.println("飞狗Moco");
}
}
调用
package com.qfedu.day07;
/**
* @Author laoyan
* @Description TODO
* @Date 2022/3/9 10:18
* @Version 1.0
*/
public class TestFlyingDemo {
public static void main(String[] args) {
Dog dog = new Dog();
dog.fly();
Plane plane = new Plane();
plane.fly();
/**
* 接口 的多态
*/
Flying dog2 = new Dog();
dog2.fly();
}
}
5、需要注意的点:
1、抽象类也可以实现接口,只是里面的方法可以实现也可以不实现。
public abstract class Animal implements Flying{
}
public class Pig extends Animal{
@Override
public void fly() {
}
}
2、一个类可以实现多个接口
public class Dog implements Flying,Running{}
3、接口和接口之间可以继承,还可以多继承
public interface ManRunning extends Running,Flying{
void manRun();
}
4、两个接口中拥有同名的,同参数的方法,但是可能返回值不同,同一个类是无法同时继承这两个接口的。冲突了。
可以出现下面这种:
6、接口的多态:
作用:
/**
*
* 继承的时候也有多态:
* Animal dog = new Dog();
* 1、参数多态
* 2、返回值多态
* 接口多态的用法: 跟继承的时候一样
* 1、参数多态
* * 2、返回值多态
* @param args
*/
public static void show(Flying fly){
fly.fly();
}
public static Flying show(){
return new Plane();
}
7、接口中的类型转换:
Flying f1 = new Dog(); // 向上转型自动的
Dog dog3 = (Dog) f1;// 向下转型,需要强制转换
因为强制类型转换有可能出现异常,所以要先判断再转换:
public static void show(Flying fly){
if(fly instanceof Dog){
Dog dog = (Dog) fly;
System.out.println("fly 是狗");
}
if(fly instanceof Plane){
Plane p= (Plane) fly;
System.out.println("fly 是飞机");
}
fly.fly();
}
抽象类一般当做半成品
电脑:
interface Computer{
// 显示器
// cpu
// 内存
//硬盘
// 贴牌以及售后
}
/* 抽象类可以当做 半成品 理解*/
abstract class SubComputer implments Computer{
// 显示器
// cpu
// 内存
//硬盘
实现以上方法
// 留下 贴牌和售后
}
class Lenovo extends SubComputer {
// 贴牌和售后
}
二、异常
1、异常的由来
Throwable 有两个儿子: Error & Exception
Error : 错误 —> 坏了
Exception : 异常 —> 两个方向 编译时异常 和 运行时异常;
编译时异常: IDEA中编写代码立即爆红 过不了编译这个时期的。 java —> class
运行时异常: 编译正确,没毛病,运行的时候报错了 ,运行时异常 RuntimeException (重点)
int[] arr = {1,2}
arr[3]; // 数组下标越界
Plane p = (Plane) dog ; // 数据类型转换异常
int a = 10 / 0 ; // 数据运算异常
2、异常出现后的处理办法
1) 可以通过try —catch 进行处理,处理了就没事儿了,否则,没人管,就交给虚拟机,虚拟机就报错。虚拟机一报错,后面代码不执行了。
try{
}catch(e){
}
异常中有一个非常常见的方法: e.printStackTrace();
作用是打印栈异常
package com.qfedu.day07_02;
/**
* @Author laoyan
* @Description TODO
* @Date 2022/3/9 14:55
* @Version 1.0
*/
public class Demo01 {
/*
public class RuntimeException extends Exception
public class ArithmeticException extends RuntimeException
我们学习的所有的异常,一般指的都是 RuntimeException
*/
public static void main(String[] args) {
//int a = 10 / 0;
divide(10,0);
System.out.println("我能出现吗?");
}
public static int divide(int a ,int b){
int i = 1;
try{
/**
* try 写业务
*/
i = a / b;
}catch(ArithmeticException e){
// 如果抓住这个异常,准备怎么处理
e.printStackTrace();
//System.out.println("快看,有异常了,还是个算数异常");
}
return i;
}
}
2) 不管了,向上抛
public static double array(int[] arr) throws ArrayIndexOutOfBoundsException {
return arr[10];
}
向上抛,抛的后果就是谁调用这个方法,谁处理,如果它也不处理,可以选择继续抛。
main --> a() --> b() -- c();
3) 万能的办法
public void add(){
try{
存放方法中的所有代码
}catch(Exception e){
e.printStackTrace();
}
}
public void add2() throws Exception{
// 不管出现啥异常,都扔出去。
}
4) 经常使用的地方
5) 可以进行多个catch 的案例:
try{
可能发生异常的代码
}catch(异常一 e){ //捕获异常 e就是要捕获的异常
对当前异常的处理
}catch(异常二 e){ //捕获异常 e就是要捕获的异常
对当前异常的处理
}catch(Exception e){ //捕获异常 e就是要捕获的异常
对当前异常的处理
}
异常一: 代表数组下标越界
异常二: 代表空指针异常
如果你写成以上的多个catch 请将最大的那个父类异常,放在最后,否则都白写了。
编程经验告诉我们:所有的异常无需搞得那么细,直接用最大的Exception 去接收即可。
try{
可能发生异常的代码
}catch(Exception e){ //捕获异常 e就是要捕获的异常
对当前异常的处理
}
6) try{} catch{} finally{}
try{
代码从上到下依次执行,一直到有异常为止。
}catch(Exception e){
e.printStackTrace();
// 异常真的出现了,才会调用这个里面的代码 -- 有很大可能不执行
}finally{
// 不管try 和 catch 执行不执行,此处的代码肯定执行。
}
finally 里面的代码一般都是关闭流或者数据库连接之类的代码
final finally 老婆和老婆饼的关系
7) throw throws
throw 经常 表示手动抛出一个具体的异常,一般在方法中出现
LostWheelException lost =new LostWheelException;
throw lost;
throws 一般出现在方法的参数的后面,表示该方法抛出了某个异常,需要调用者进行处理。
8) 自定义异常
package com.qfedu.day07_02;
/**
* @Author 千锋大数据教学团队
* @Company 千锋好程序员大数据
* @Description 自定义的异常类
*/
class FuShuException extends Exception{
// 异常的描述信息
// 在根类 Throwable 中,有一个私有的属性 detailMessage,存储异常的描述信息。
// 在自定义异常描述信息的时候,只需要添加一个有参的构造方法即可完成
public FuShuException(){}
public FuShuException(String message){
//这行代码必须写
// 调用父类中的构造方法,
// 在父类中,再调用它的父类中的构造方法,一层层向上调用,最终可以调用到Throwable类中的有参构造
// 实现对 detailMessage 属性的赋值。
super(message);
}
}
public class Demo02 {
public static void main(String[] args) //throws FuShuException
{
Math math = new Math();
try {
math.div(2,-3);
} catch (FuShuException e) {
e.printStackTrace();
}
}
}
class Math{
//异常的声明(我们要给可能发生异常的方法进行异常的声明)----throws 作用:告诉别人我有可能发生异常
public int div(int a,int b) throws FuShuException
{
if (b < 0){
//创建异常对象并抛出
throw new FuShuException("除数为负数了");
}
return a/b;
}
}
三、枚举
1、枚举的例子
package com.qfedu.day07_03;
/**
* @Author laoyan
* @Description TODO
* @Date 2022/3/9 16:37
* @Version 1.0
*/
public class TestEnum {
public static void main(String[] args) {
Season season = Season.AUTUMN;
switch (season) {// int,char,String,枚举,byte,short,包装类
case SPRING:
System.out.println("春天来了");
break;
case SUMMER:
System.out.println("夏天来了");
break;
case AUTUMN:
System.out.println("秋天来了");
break;
case WINTER:
System.out.println("冬天来了");
break;
default:
System.out.println("其他季节");
break;
}
}
}
2、语法:
public enum Gender {
// 将这个枚举对象所有可能取到的值, 都列出来
// 枚举中的元素, 也是标识符, 遵循大驼峰命名法
Male, Female
}
public enum Month {
Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec
}
public enum Week {
Mon, Tue, Wed, Thu, Fri, Sat, Sun
}
枚举类型一般用于表示一类数据,比如月份、性别、四季、周天。
3、作用
1)可以替代常量的表达,见名知意。
2) 如果觉得看见名字还不够,还想携带更多的信息,可以通过枚举中的构造方法来表示。
public enum OrderPayLogPaymentStatusEnum {
//public static final WAITING_TRANSFER = 1;
//public static final HAVE_TRANSFERRED = 2;
/**
* 未支付
*/
WAITING_TRANSFER("1", "未支付"),
/**
* 未支付
*/
HAVE_TRANSFERRED("2", "已支付");
private String code;
private String param;
OrderPayLogPaymentStatusEnum(String code, String param) {
this.code = code;
this.param = param;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getParam() {
return param;
}
public void setParam(String param) {
this.param = param;
}
}
4、代码
package com.qfedu.day07_03;
/**
* @Author laoyan
* @Description TODO
* @Date 2022/3/9 16:36
* @Version 1.0
*/
public enum Season { // 枚举类
SPRING("春"),SUMMER("夏"),AUTUMN("秋"),WINTER("冬");
String desc;
Season(String desc){
this.desc = desc;
}
}
package com.qfedu.day07_03;
/**
* @Author laoyan
* @Description TODO
* @Date 2022/3/9 16:49
* @Version 1.0
*
*
* 1、枚举其实就是一个特殊的类 --> 枚举类
* 拥有Object的所有方法。
* 2、 SRPING 其实就是Season 枚举类的实例化对象
* 3、toString方法返回的是一个名字
* 4、枚举不能被其他类或者枚举类继承。
* 5、枚举类中可以写其他属性
* 6、枚举类还可以写构造方法,一旦写了一个有参数的,无参数的构造方法自动消失,之前的实例化对象也会报错
* 7、枚举类中可以编写普通方法和静态方法。但是作用不大。一般不写
* 8、枚举可以继承接口,还可以重写Object中的方法 ,一般不写
*
*/
public class Demo01 {
public static void main(String[] args) {
Season s1 = Season.SPRING; //
System.out.println(s1.toString());
System.out.println(Season.SPRING);
System.out.println(Season.SUMMER.getDesc());
}
}