一、接口
(一)概述
1、广义:一切定义规则的事物都是接口
2、侠义:
Java
中用于定义方法声明的规则就是接口,
Java
的接口中,定义的所有方法都是抽象的
3、好处:将方法的调用和方法的实现分离开了吗,可以降低代码的耦合度,提升开发效率
(二)接口的特点
1、定义格式
public interface 接口名 {
}
2、接口中只能声明定义抽象方法,不能有方法的实现
3、接口的实现,使用类,用过
implements
关键字来实现接口
(1)格式
class 类名 implements 接口名 {
}
(2)接口中只有方法的声明没有实现,我们通过类来实现接口,不同的类可以实现相同的接口,给予接 口不同的实现
4、接口实现类的用于
(1)当接口的实现类实现了接口中所有的抽象方法,这个类就是一个普通类,可以创建对象调用方法
(2)当接口的实现类没有完全实现接口中的抽象方法时,那么此时这个类就是一个抽象类,就需要进一 步通过子实现类继承抽象类中的抽象方法
public class Demo01_Inter {
}
/**
* 接口
*/
interface MyInter {
public abstract void test1();
public abstract void test2();
}
abstract class MyClass implements MyInter {
@Override
public void test1() {
//当抽象类实现了接口中的一部分抽象方法的时候,子实现类就可以不同实现这部分
}
}
class MySon extends MyClass {
@Override
public void test2() {
}
}
(三)接口中成员特点
1、成员变量:没有。接口中只能定义常量不能定义变量!当我们定义一个常量时,会默认加上【
public static final】,建议手动加上
2、成员方法:只有抽象方法。默认会省略【
public abstract
】建议手动加上
3、构造方法:没有。接口中不能定义变量,没有赋值的需求
public class Demo02_InnerInterface {
}
interface MyInter01 {
//常量
public static final int MAX = 100;
//静态方法
public static void test2() {}
//成员变量
//String name;
//成员方法
//public void test() {}
//抽象方法
public abstract void test1();
//构造方法
//public MyInter01() {}
}
(四)类与类、类与接口、接口与接口
1、类与类:继承关系,使用关键字
extends
,支持:单继承、多层继承
2、类与接口:实现关系,使用
implements
关键字
(1)支持单实现、多实现;
(2)单实现
class 类名 implements 接口名 {
实现接口中所有的抽象方法
}
abstract class 类名 implements 接口名 {
实现接口中部分的抽象方法
}
(3)多现实
class 类名 implements 接口名1, 接口名2, 接口名3... {
实现所有接口中所有的抽象方法
}
abstract class 类名 implements 接口名1, 接口名2, 接口名3... {
实现接口中部分的抽象方法
}
(4)一个类在实现多个接口的同时,还可以继承一个类
class 类名 extends 父类 implements 接口名1, 接口名2, 接口名3... {
实现所有接口中所有的抽象方法
重写父类中的方法
}
abstract class extends 父类 类名 implements 接口名1, 接口名2, 接口名3... {
实现接口中部分的抽象方法
重写父类中的方法
}
3、接口与接口:继承关系,支持:单继承、多继承、多层继承
多继承的格式
interface 接口 extends 接口名1, 接口名2, 接口名3... {
相当于整合了所有接口中的抽象方法
}
4、设计思路
(1)类一般用于定义事物固有的属性和行为
(2)接口一般用于定义事物通过扩展获取学习而来的功能
(五)案例:会跳高的猫
设计:动物类:姓名,年龄,吃饭,猫类(捉老鼠),狗类(看家)
设计一个动物培训接口,可以培训跳高
会跳高的猫类【封装、继承、抽象、接口】
public class Demo03_Cat {
/**
* 设计:动物类:姓名,年龄,吃饭,猫类(捉老鼠),狗类(看家)
* 设计一个动物培训接口,可以培训跳高
* 会跳高的猫类【封装、继承、抽象、接口】
*/
public static void main(String[] args) {
Cat cat = new Cat("汤姆", 3);
cat.eat();
cat.catchMouse();
System.out.println(cat.toString());
Dog dog = new Dog("山姆", 5);
dog.eat();
dog.lookHome();
System.out.println(dog.toString());
JumpCat jc = new JumpCat("跳猫", 2);
jc.eat();
jc.catchMouse();
jc.jump();
System.out.println(jc.toString());
}
}
/**
* 动物类
*/
abstract class Animal {
private String name;
private int age;
public abstract void eat();
@Override
public String toString() {
return "Animal{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Animal() {
}
public Animal(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;
}
}
/**
* 猫类
*/
class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
public void catchMouse() {
System.out.println("猫捉老鼠");
}
public Cat() {
}
public Cat(String name, int age) {
super(name, age);
}
}
/**
* 狗类
*/
class Dog extends Animal {
@Override
public void eat() {
System.out.println("够吃狗粮");
}
public void lookHome() {
System.out.println("狗看家");
}
public Dog() {
}
public Dog(String name, int age) {
super(name, age);
}
}
/**
* 接口
*/
interface Jumping {
public abstract void jump();
}
/**
* 会跳高的猫类
*/
class JumpCat extends Cat implements Jumping {
@Override
public void jump() {
System.out.println("培训之后会跳高");
}
public JumpCat() {
}
public JumpCat(String name, int age) {
super(name, age);
}
}
二、多态
(一)概述
1、多态:事物的多种状态
2、对象的多态性:同一个对象,可能具有不同的名称,可以有不同的类型的引用指向他。本质:同一个 对象,有不同的名称和描述
3、类的多态性:同一个类型,可能还具有不同的子类,同一个类型的引用,可以指向不同的子类对象。
本质:同一个名字和描述,可能在不同的场景下有不同的实现。
4、多态的前提
(1)要有继承关系
(2)有方法的重写
(3)父类引用指向子类对象
(二)成员变量的特点
1、编译看左边,运行看左边
2、编译看左边:如果左侧父类中没有定义相关的变量,编译期就会报错
3、运行看左边:如果左侧有对应的成员变量,就会执行父类中的成员变量
(三)成员方法的特点
1、编译看左边,运行看右边
2、编译看左边:如果左侧父类中没有定义相关的方法,编译期就会报错
3、运行看右边:如果右侧所属类型中有对应的方法,就执行对象所属类型中的方法
(四)钢铁侠案例
1、向下转型
(1)在多态中是父类引用指向子类对象,讨论的范畴是基于父类的范畴
(2)如果子类对象想要执行自己所属类型的特有方法以及成员变量,就要从父类引用指向子类对象变为 子类引用指向子类对象
(3)格式
(目标类型) 需要转化的类型;
(4)恢复了子类对象后原本具有的访问范围
2、向上转型
(1)原本使用子类引用指向子类对象,变成了父类引用指向子类对象。
(2)本质:缩小了访问的范围,减少了访问的权限
public class Demo06_IronMan {
public static void main(String[] args) {
Man m = new IronMan();
System.out.println(m.name);
m.dealBusiness();
//m.fly();
//向下转型
IronMan im = (IronMan) m;//IronMan im = new IronMan();
System.out.println(im.name);
im.dealBusiness();
im.fly();
//向上转型
IronMan im2 = new IronMan();
Man m2 = im2;//Man m2 = new IronMan();
System.out.println(m2.name);
m2.dealBusiness();
}
}
class Man {
String name = "托尼史塔克";
public void dealBusiness() {
System.out.println("谈生意");
}
}
class IronMan extends Man {
String name = "钢铁侠";
public void dealBusiness() {
System.out.println("谈几个亿的大生意");
}
public void fly() {
System.out.println("飞");
}
}
(五)多态的好处
1、提供了代码的可扩展性
2、在方法的参数列表中定义父类的引用,将来传入子类的对象都可以使用
public class Demo07_Juicing {
public static void main(String[] args) {
Juicing j = new Juicing();
j.makeJuice(new Apple());
j.makeJuice(new Pear());
j.makeJuice(new Mango());
}
}
/**
* 榨汁机
*/
class Juicing {
/*public void makeJuice(Apple a) {//Apple a = new Apple()
a.flow();
}
public void makeJuice(Pear p) {//
p.flow();
}*/
public void makeJuice(Fruit f) {
f.flow();
}
}
abstract class Fruit {
public abstract void flow();
}
/**
* 苹果类
*/
class Apple extends Fruit {
@Override
public void flow() {
System.out.println("流出苹果汁");
}
}
/**
* 梨
*/
class Pear extends Fruit {
@Override
public void flow() {
System.out.println("流出梨汁");
}
}
/**
* 芒果
*/
class Mango extends Fruit {
@Override
public void flow() {
System.out.println("流出芒果汁");
}
}
(六)instanceof
1、
instanceof
,关键字:是一个运算符,结果是一个布尔类型的值
2、格式
A instanceof B
3、作用:
A
是一个对象,
B
是一个类型;判断
A
对象是否和
B
类型有关;
4、有关:
A
对象是
B
类型的对象;
A
对象是
B
类型子类的对象
public class Demo08_Instanceof {
public static void main(String[] args) {
Painter p = new Painter();
p.drawPicture(new Pen());
p.drawPicture(new DrawPen());
p.drawPicture(new Brush());
p.drawPicture(new EyePen());
}
}
/**
* 笔的总父类
*/
class Pen {
public void write() {
System.out.println("画出印记");
}
}
/**
* 眼线笔类
*/
class EyePen extends Pen {
}
/**
* 画笔类
*/
abstract class Pencil extends Pen {
public abstract void drawing();
}
/**
* 毛笔类
*/
class DrawPen extends Pencil {
@Override
public void drawing() {
System.out.println("画水墨画");
}
}
/**
* 排笔
*/
class Brush extends Pencil {
@Override
public void drawing() {
System.out.println("画油画");
}
}
/**
* 画家类
*/
class Painter {
public void drawPicture(Pen p) {//Pen p = new Pen();
//判断当前的笔能不能画画
if (p instanceof Pencil) {
//如果是画笔类的对象,就可以画画
//因为执行的方法是子类特有的方法,所以需要进行类型转换
Pencil pe = (Pencil) p;
pe.drawing();
} else {
p.write();
}
}
}
三、final关键字
1、
final
:关键字,含义:不可更改的
2、可以修饰的内容
(1)修饰类:类不能被继承
(2)修饰成员变量:变量变为常量
(3)修饰方法:方法不能被重写
3、
final
通常被用在定义常量【
public static final int MAX = 100;
】
public class Demo09_Final {
}
class C {
//修饰变量,变量变常量
final int num = 10;
public void show() {
//num = 20;
}
//修饰方法方法不能被重写
public final void test() {}
}
class D extends C {
/*@Override
public void test() {
super.test();
}*/
}
//修饰类类不能被继承
final class A { }
//class B extends A {}
四、System
1、用于描述系统资源的类型,不能创建对象,类中的方法都是静态的,使用类名进行调用
2、常用字段
(1)System.out
:标准输出流,默认关联控制台
(2)System.in
:标准输入流,默认关联键盘
(3)System.err
:错误打印流,默认关联控制台
3、常用方法
(1)
gc
()
:运行垃圾回收器
(2)
currentTimeMillis
()
:获取时间毫秒值。
public class Demo10_System {
public static void main(String[] args) {
System.out.println("标准输出流");
System.err.println("错误打印流");
System.out.println(System.currentTimeMillis());
new Rubbish();
System.gc();
}
}
class Rubbish {
@Override
protected void finalize() throws Throwable {
System.out.println("啊!!!");
}
}
五、接口用法补充
public class Demo11_Test {
public static void main(String[] args) {
new MyClass02().show(new Son());
}
}
//接口
interface MyInter02 {
public abstract void test();
}
//接口的子实现类
class Son implements MyInter02 {
@Override
public void test() {
System.out.println("son");
}
}
//其他类
class MyClass02 {
//MyInter02 mi;
//将接口的声明引用可以定义在类中或者方法的参数列表中,
// 因为接口没有办法创建对象,将来传进来接口的子实现类对象即可
public void show(MyInter02 mi) {
mi.test();
}
}