1. 接口的实现
interface USB{
//常量:定义的USB的尺寸等
void start();
void stop();
}
class Printer implements USB{//打印机
@Override
public void start() {
System.out.println("打印机开始工作");
}
@Override
public void stop() {
System.out.println("打印机结束工作");
}
}
class KeyBoard implements USB{
@Override
public void start() {
System.out.println("键盘开始工作");
}
@Override
public void stop() {
System.out.println("键盘结束工作");
}
}
public class USBTest {
public static void main(String[] args) {
//1. 创建了接口的实现类的对象
Printer printer = new Printer();
// operate(printer);
//2. 创建了接口的实现类的匿名对象
// operate(new KeyBoard());
//3. 创建接口的匿名实现类的对象
USB usb1 = new USB(){
public void start(){
System.out.println("mp3开始工作");
}
public void stop(){
System.out.println("mp3结束工作");
}
};
// operate(usb1);
//4. 创建接口的匿名实现类的匿名对象
operate(new USB(){
@Override
public void start() {
System.out.println("电纸书开始工作");
}
@Override
public void stop() {
System.out.println("电纸书结束工作");
}
});
}
public static void operate(USB usb){ //USB usb = new Printer();
System.out.println("========检测外部设备=========");
usb.start();
System.out.println("==========具体的数据传输过程===========");
usb.stop();
}
}
相对应的,抽象类也可以考虑使用匿名子类的方式。比如:
abstract class Person {
String name;
int age;
public abstract void eat();
public void walk(){
System.out.println("人:走路");
}
}
abstract class Order{
public void method(){
System.out.println("method");
}
}
public class PersonTest {
public static void main(String[] args) {
//创建Person类的匿名子类的对象
Person p1 = new Person(){
@Override
public void eat() {
System.out.println("工人吃饭");
}
};
p1.eat();
System.out.println(p1.getClass());
Order order = new Order(){};
order.method();
}
}
2. 接口的新特性
/* jdk8新特性:
* 静态方法(有方法体)、默认方法(有方法体)
* jdk9新特性:
* 私有方法
*/
知识点1:接口中的静态方法只能被接口调用,实现类不可以调用
知识点2:实现类可以重写接口中的默认方法
— 1)实现类如果没有重写接口中的默认方法,则实现类的对象调用的是接口中的默认方法
— 2) 实现类如果重写了接口中的默认方法,则实现类的对象调用的是重写的后的方法
知识点3:如果实现类实现的多个接口中定义了同名同参数的方法,则在实现类没有重写此方法的情况下,会报错—> 接口冲突为了避免接口冲突,要求实现类必须重写此同名同参数的方法。
知识点4:如果子类(或实现类)继承的父类和实现的接口中定义了同名同参数的方法,则在子类(或实现类)没有重写此方法的情况下,不会报错。默认调用的是父类中声明的方法。—>类优先原则
知识点5:如何调用接口中的默认方法。见下面
interface CompareA{
//静态方法
public static void method1(){
System.out.println("CompareA:武汉");
}
//默认方法
public default void method2(){
System.out.println("CompareA:北京");
}
default void method3(){
System.out.println("CompareA:上海");
}
default void method4(){
System.out.println("CompareA:深圳");
}
}
interface CompareB{
default void method3(){
System.out.println("CompareB:上海");
}
}
class SuperClass{
public void method4(){
System.out.println("SuperClass:深圳");
}
}
class SubClass extends SuperClass implements CompareA,CompareB{
public void method2(){
System.out.println("SubClass:北京");
}
public void method3(){
System.out.println("SubClass:上海");
}
public void method(){
super.method4();//调用的是父类中声明的方法
CompareA.super.method3();//调用接口中的默认方法
CompareB.super.method3();
}
}
3.相关练习
/**
* 定义一个接口用来实现两个对象的比较。
* interface CompareObject{
* public int compareTo(Object o); //若返回值是 0 , 代表相等; 若为正数,代表当前对象大;负数代表当前对象小
* }
*/
public interface CompareObject {
//若返回值是 0 , 代表相等; 若为正数,代表当前对象大;负数代表当前对象小
int compareTo(Object o);
}
/**
* 定义一个Circle类,声明redius属性,提供getter和setter方法
*
*/
public class Circle {
private double radius;//半径
@Override
public String toString() {
return "Circle{" +
"radius=" + radius +
'}';
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public Circle(double radius) {
this.radius = radius;
}
public Circle() {
}
}
package com.atguigu.exer1;
/**
* 定义一个ComparableCircle类,继承Circle类并且实现CompareObject接口。
* 在ComparableCircle类中给出接口中方法compareTo的实现体,用来比较两个圆的半径大小。
*
*/
public class ComparableCircle extends Circle implements CompareObject{
public ComparableCircle(double radius) {
super(radius);
}
public ComparableCircle() {
}
@Override
public int compareTo(Object o) {
if(this == o){
return 0;
}
if(o instanceof ComparableCircle){
ComparableCircle c = (ComparableCircle)o;
// return (this.getRadius() > c.getRadius())? 1 : ((this.getRadius() == c.getRadius())? 0 : -1);
return Double.compare(this.getRadius(),c.getRadius());
}
// throw new RuntimeException("输入的类型不匹配");
return 0;
}
}
/**
* 定义一个测试类InterfaceTest,创建两个ComparableCircle对象,调用compareTo方法比较两个类的半径大小。
*
*/
public class InterfaceTest {
public static void main(String[] args) {
CompareObject c1 = new ComparableCircle(2.3);
CompareObject c2 = new ComparableCircle(2.4);
System.out.println(c1.compareTo(c2));
}
}
4. 类的成员之五:内部类
* 类的成员之五:内部类(innerclass)
*
* 1. 分类:成员内部类: 静态的成员内部类、非静态的成员内部类
* 局部内部类:方法内、构造器内、代码块内
2. 内部类的内容需要大家掌握的有如下三个点:
* ① 如何创建成员内部类的实例
* ② 如何在成员内部类中调用外部类的相关结构
* ③ 关于局部内部类的常见使用的掌握
4.1 成员内部类
* 3. 理解成员内部类:
* 一方面,内部类作为类:
* > 内部可以定义属性、方法、构造器、代码块、内部类....
* > 可以被final修饰
* > 可以被abstract修饰
*
* 另一方面,内部类作为外部类的成员:
* > 可以被4种权限修饰结构来修饰
* > 可以被static修饰
* > 可以调用外部类的结构:属性、方法、。。。
class Person{
String name = "Tom";
//静态的成员内部类
public static class Dog{
public void shout(){
System.out.println("汪~汪~汪~");
}
}
//非静态的成员内部类
public class Bird{
String name = "布谷鸟";
public void shout(){
System.out.println("喳~喳~喳~");
}
public void show(String name){
System.out.println(name);//show()的形参
System.out.println(this.name);//Bird类中的成员变量
System.out.println(Person.this.name);//外部类的成员变量
this.eat();
Person.this.eat();
}
public void eat(){
System.out.println("鸟找食物吃");
}
}
public void method(){
//局部内部类
class A{
}
}
public Person(){
//局部内部类
class B{
}
}
{
//局部内部类
class C{
}
}
public void eat(){
int num = 1;
System.out.println("人吃饭");
}
}
public class InnerClassTest {
public static void main(String[] args) {
//1.创建静态的成员内部类的对象
Person.Dog dog = new Person.Dog();
dog.shout();
//2. 创建非静态的成员内部类的对象
// Person.Bird bird = new Person.Bird();
Person p = new Person();
Person.Bird bird = p.new Bird();
bird.shout();
System.out.println();
bird.show("黄鹂");
}
}
4.2 局部内部类的使用
/**
*
* 关于局部内部类的常见使用的掌握
*
*/
public class InnerClassTest1 {
//局部内部类的如下场景少见
public void method(){
//内部类
class InnerClass{
}
//使用内部类
}
public Comparable getInstance(){
//内部提供一个接口的实现类
// class MyComparable implements Comparable{
//
// @Override
// public int compareTo(Object o) {
// return 0;
// }
// }
//
// return new MyComparable();
//上述代码可以修改为:创建接口的匿名实现类的匿名对象
return new Comparable(){
@Override
public int compareTo(Object o) {
return 0;
}
};
}
}
Button btn = XXX.getButtonById("btn001");
btn.setOnClickListener(new ClickListener(){
public void click(){
alert("haha");
}
});
5. 异常的体系结构
* 一、异常的体系结构:
* java.lang.Throwable
* |----java.lang.Error :错误 ,我们不编写针对性的代码进行处理。
* |----StackOverflowError \ OutOfMemoryError
* |----java.lang.Exception : 异常,我们可以编写针对性的代码进行处理
* |---编译时异常:
* |---FileNotFoundException
* |---IOException
* |---运行时异常:
* |----InputMismatchException
* |----ArrayIndexOutOfBoundsException
* |----NullPointerException
* |----ClassCastException
* |----NumberFormatException
* |----ArithmeticException
*
*
* 复习:java程序执行过程分为:过程一:编译:javac.exe --->此过程中出现的异常,称为:编译时异常
* 过程二:运行:java.exe --->此过程中出现的异常,称为:运行时异常
6. 常见的“异常”及举例
6.1 Error
/**
*
* Error: Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源耗尽等严重情况。比如:StackOverflowError和OOM。
*
* 一般不编写针对性的代码进行处理。
*
*/
public class ErrorTest {
public static void main(String[] args) {
//StackOverflowError
// main(args);
//设置虚拟机参数:-Xms50m -Xmx50m
//报错误:OutOfMemoryError:Java heap space
byte[] arr = new byte[1024 * 1024 * 100];//100MB
}
}
6.2 Exception
public class ExceptionTest {
//InputMismatchException
@Test
public void test1(){
Scanner scan = new Scanner(System.in);
System.out.println("请输入你的年龄:");
int age = scan.nextInt();
System.out.println(age);
}
//ArrayIndexOutOfBoundsException
@Test
public void test2(){
int[] arr = new int[10];
System.out.println(arr[-1]);
}
//NullPointerException
@Test
public void test3(){
//情况1:
// int[] arr = null;
// System.out.println(arr[0]);
//情况2:
// int[][] arr = new int[10][];
// System.out.println(arr[0][0]);
//情况3:
String str = "hello";
str = null;
System.out.println(str.toString());//bank.getCustomer(0).getAccount().withdraw(500);
}
//ClassCastException
@Test
public void test4(){
Object obj = new String("hello");
Date date = (Date)obj;
}
//NumberFormatException:数字转换异常
@Test
public void test5(){
String str = "123";
str = "123a";
int num = Integer.parseInt(str);
System.out.println(num);
}
//ArithmeticException:算术异常
@Test
public void test6(){
int m = 10;
int n = 0;
System.out.println(m / n);
}
@Test
public void test7(){
// File file = new File("hello.txt");
// FileReader fr = new FileReader(file);
// char[] buffer = new char[4];
// int len;
// while((len = fr.read(buffer)) != -1){
// String str = new String(buffer,0,len);
// System.out.print(str);
// }
// fr.close();
}
}
7. 异常的处理方式一:try-catch-finally
7.1 异常处理的概述
* 二、异常(Exception)的处理
* * 有两种方式:方式一:try-catch-finally 方式二:throws + 异常类型
* * Java提供的是异常处理的抓抛模型。
* 程序执行过程中,出现了异常,并处理异常,对应着两个过程。
* 过程一:“抛”:程序执行过程中,一旦出现异常,就会在异常位置生成一个对应异常类型的对象,并将此
* 对象抛出。
* * 过程二:“抓” 可以广义的理解为异常处理的两种方式。
7.2 try-catch
* 三、try-catch-finally的使用
* * try{
* //可能出现异常的代码
* * }catch(XxxException e){
* 处理异常的方式
* }catch(XxxException e){
* 处理异常的方式
* }
* ...
* finally{
* 一定会被执行的代码
* }
* * 说明:
* 1. finally是可选的。
* 2. try中声明的变量,在出了try结构之后就失效了
* 3.
* ① 执行try中的代码时,一旦执行过程中出现异常,则会在指定代码的位置生成相应的异常类的对象,并将此
* 对象抛出。之后try中的代码不再执行。
* ② 抛出的对象根据其类型依次匹配try后面的catch,一旦匹配成功,就进入catch结构,进行异常的处理。处理完以后,
* 不再匹配其后的catch结构,而是跳出try-catch继续执行其后的代码。
* 4. 如果声明了多个catch结构,且多个catch中的异常类型没有子父类关系,则多个catch结构谁先声明,谁后声明都可以。
* 如果多个catch中的异常类型满足子父类的关系,则子类异常类型必须声明在父类异常类型的上面,否则报错。
* * 5. 常见的catch中异常处理的方式:
* ① 自定义输出信息
* ② 异常类的方法:getMessage() / printStackTrace()
* * 6. 经验:
* ① 实际开发中,针对于运行时异常,通常我们就选择不进行异常的处理了。
* ② 实际开发中,针对于编译时异常,我们必须进行异常的处理,否则编译不通过。
* 进行try-catch处理以后,就可以编译通过。那运行是否可以通过,就需要真正执行来看了。
* * 7. try-catch-finally结构可以嵌套使用
- 代码举例
public class ExceptionTest1 {
//NumberFormatException:数字转换异常
@Test
public void test1(){
try {
String str = "123";
str = "123a";
int num = Integer.parseInt(str);//生成了一个NumberFormatException类的对象
System.out.println(num);
}catch(NullPointerException e){
System.out.println("出现了空指针的异常.....");
}catch(NumberFormatException e){
//处理方式
System.out.println("出现了数字转换异常....");
}catch(Exception e){
System.out.println("出现了异常....");
}
System.out.println("hello!");
}
//NullPointerException
@Test
public void test2(){
try{
String str = "hello";
str = null;
System.out.println(str.toString());
}catch(NullPointerException e){
// System.out.println(e.getMessage());
e.printStackTrace();
}
}
//ClassCastException
@Test
public void test3(){
try{
Object obj = new String("hello");
Date date = (Date)obj;
}catch(ClassCastException e){
e.printStackTrace();
}
}
@Test
public void test7(){
try {
File file = new File("hello.txt");
FileReader fr = new FileReader(file);
char[] buffer = new char[4];
int len;
while ((len = fr.read(buffer)) != -1) {
String str = new String(buffer, 0, len);
System.out.print(str);
}
fr.close();
}catch(FileNotFoundException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
}
}
7.3 finally
/**
* 测试finally的使用
*
* 1. 体会finally中存放一定会被执行的代码。
* 说明:不管try、catch中是否存在未被处理的异常,不管是否存在return语句等。finally都要被执行的。
*
* 2. 什么样的代码需要声明在finally中呢?
* 涉及到系统相关资源的位置。比如:IO流、网络Socket、数据库连接等
*
*/
public class FinallyTest {
@Test
public void test1() {
try {
System.out.println( 10 / 0);
File file = new File("hello.txt");
FileReader fr = new FileReader(file);
char[] buffer = new char[4];
int len;
while ((len = fr.read(buffer)) != -1) {
String str = new String(buffer, 0, len);
System.out.print(str);
}
fr.close();
}catch(IOException e){
e.printStackTrace();
}
System.out.println("程序执行结束");
}
@Test
public void test2() {
try {
System.out.println(10 / 0);
File file = new File("hello.txt");
FileReader fr = new FileReader(file);
char[] buffer = new char[4];
int len;
while ((len = fr.read(buffer)) != -1) {
String str = new String(buffer, 0, len);
System.out.print(str);
}
fr.close();
}catch(IOException e){
e.printStackTrace();
}finally{
System.out.println("程序执行结束");
}
}
@Test
public void test3(){
System.out.println(method1());
}
public int method1(){
try{
return 1;
}catch(Exception e){
e.printStackTrace();
}finally{
return 2;
}
}
@Test
public void test4() {
FileReader fr = null;
try {
File file = new File("hello.txt");
fr = new FileReader(file);
char[] buffer = new char[4];
int len;
while ((len = fr.read(buffer)) != -1) {
String str = new String(buffer, 0, len);
System.out.print(str);
}
}catch(IOException e){
e.printStackTrace();
}finally{
//流资源的关闭操作。此操作必须执行,否则会出现内存的泄漏
try {
if(fr != null)
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("程序执行结束");
}
}