接口和多态等
接口:
指的是方法的集合,是java中的一种引用类型,接口中的方法包括:方法,抽象方法,默认方法,静态方法和私有方法。
接口不是类,而是一种引用类型。
**引用数据类型:**数组,类,接口
接口不能创建对象,但是接口可以被实现(类似于继承)。一个实现了接口的类,需要实现接口中所有的抽象方法。
默认方法:
使用 default修饰,不可省略,提供给子类调用或者子类重写。
私有方法:
使用private修饰,提供给接口中的默认方法或者静态方法调用。
非抽象子类实现接口:
1.必须重写接口中所有的抽象方法。
2.继承了接口中的默认方法,既可以直接调用,也可以重写。
静态方法与.class文件相关,只能使用接口名进行调用,不可以通过实现类的类名或者实现类的对象进行调用。
接口的多实现:
之前在继承中我们知道继承只能单继承,但是接口可以多实现,就是一个类可以实现多个接口。
接口中的抽象方法:
实现类必须重写接口的所有抽象方法,但是一个接口如果只有多个名字一样的话,实现类只需要重写一次就可以了。
静态方法:
接口中,存在同名的静态方法并不会产生冲突,原因是只能通过各自接口名访问静态方法。
优先级问题:
当一个类继承一个父类并且实现一个接口是,父类中的成员方法与接口中的方法重名时,子类就近执行父类的成员方法。
其他特点:
接口中没有办法定义成员变量,但可以定义常量,他的值不可以改变,被public static final修饰
接口中没有构造方法,也不能创建对象
接口中没有静态代码块
多态:
是指同一行为,有不同的表现形式。
package com.rongyu.day08;
/**
* 定义动物抽象类
*/
public abstract class Animal {
public abstract void eat();
}
package com.rongyu.day08;
/**
* 定义猫类
*/
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("我是一只猫,我爱吃鱼!");
}
}
package com.rongyu.day08;
/**
* 定义狗类
*/
public class Dog extends Animal {
@Override
public void eat() {
System.out.println("我是一只狗,我喜欢吃骨头!");
}
}
package com.rongyu.day08;
/**
* 实现多态测试
*/
public class TestAnimal {
public static void main(String[] args) {
Animal animal = new Cat();
animal.eat();
Animal animal1 = new Dog();
animal1.eat();
}
}
运行结果:
多态的好处:
实际开法中,父类作为方法的形式参数,传递子类对象给方法,进行方法的调用。
引用数据类型的转换:
向上转型:多态本身就是子类类型向父类类型转化的过程。
向下转型:父类类型向下转型的过程,这个类型是强制的。
instanceof关键字:
如果变量属于该数据类型,返回true
如果变量不属于该数据类型则返回false
笔记本案例:
package com.rongyu.day08;
/**
* 笔记本电脑
*/
public interface USB {
void open();
void close();
}
package com.rongyu.day08;
/**
* 定义鼠标类
*/
public class Mouse implements USB {
@Override
public void open() {
System.out.println("鼠标打开了!");
}
@Override
public void close() {
System.out.println("鼠标关闭了!");
}
public void click(){
System.out.println("鼠标进行单击!");
}
}
package com.rongyu.day08;
public class KeyBoard implements USB {
@Override
public void open() {
System.out.println("键盘开启了!");
}
@Override
public void close() {
System.out.println("键盘关闭了!");
}
public void dazi(){
System.out.println("键盘进行打字!");
}
}
package com.rongyu.day08;
/**
* 定义笔记本类
*/
public class Laptop {
public void run(){
System.out.println("笔记本开始运行!");
}
public void useUSB(USB usb){
if (usb!=null){
usb.open();
if (usb instanceof Mouse){
Mouse mouse = (Mouse)usb;
mouse.click();
}else if (usb instanceof KeyBoard){
KeyBoard keyBoard = (KeyBoard)usb;
keyBoard.dazi();
}
usb.close();
}
}
public void closeRun(){
System.out.println("笔记本关闭!");
}
}
package com.rongyu.day08;
/**
* 测试多态
*/
public class TestLaptop {
public static void main(String[] args) {
Laptop laptop = new Laptop();
laptop.run();
USB usb = new Mouse();
USB usb1 = new KeyBoard();
laptop.useUSB(usb);
laptop.useUSB(usb1);
laptop.closeRun();
}
}
总结:
接口为引用数据类型,所以通过接口可以创建子类对象,但是要通过给笔记本里面写出使用usb的方法,通过instanceof 知道他属于什么数据类型,然后就直接调用该类的方法。
final关键字:
不可改变,用于修饰类方法和变量。
final修饰引用数据类型:
被修饰后的引用数据类型只能指向一个对象,地址不能再改变,但是不影响对象内部成员变量值的修改。
package com.rongyu.day08;
public class User {
String username;
}
package com.rongyu.day08;
/**
* 测试final修饰引用数据类型
*/
public class Dome01 {
public static void main(String[] args) {
final User user = new User();
user.username = "zhangsan";
System.out.println(user.username);
}
}
可以看出来username的值还是可以修改的,只是user的地址不会发生改变。
包的作用:
允许类组成较小的单元(类似于文件夹),易于找到和使用相应的文件。
防止命名冲突,区分名字相同的类。
有助于实施访问权限的控制。
创建包:
package 包名;
导入包:
import 包名。类名;
注意:
package和import的位置是固定的
package必须位于第一行
只允许有一个package的语句
其次才是import
每个包都是独立的
顶层包不会包含子包的类
权限修饰符:
public 公共的
protected 受保护的
default 默认的
private 私有的
成员变量使用private
构造方法使用public
成员方法使用public
不加修饰符 访问能力和default 相同
内部类:
将类A定义到类B中,类A就称为内部类,B则称为外部类。
内部类可以直接访问外部类的成员包括私有成员
外部类访问内部类的成员,必须建立内部类的对象
匿名内部类:
内部类的简化写法,本质是一个带具体实现的父类或者父接口的匿名的子类对象。
接口的直接创建就是一种匿名内部类。
引用类型方法总结:
class作为成员变量
接口作为方法参数和返回值类型
比如List 和 ArrayList
package com.rongyu.day08;
public class Wuqi {
private String name;
private int shanghai;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getShanghai() {
return shanghai;
}
public void setShanghai(int shanghai) {
this.shanghai = shanghai;
}
}
package com.rongyu.day08;
public class Kuijia {
private String name;
private int fangyu;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getFangyu() {
return fangyu;
}
public void setFangyu(int fangyu) {
this.fangyu = fangyu;
}
}
package com.rongyu.day08;
public interface Fashu {
void fashu();
}
package com.rongyu.day08;
public class Role {
private int id;
private int blood;
private String name;
private Wuqi wuqi;
private Kuijia kuijia;
private Fashu fashu;
//攻击方法
public void gongji(){
System.out.println("使用"+wuqi.getName()+"造成了"+wuqi.getShanghai()+"点伤害!");
}
//穿戴盔甲
public void fangyu(){
this.blood += kuijia.getFangyu();
System.out.println("使用"+kuijia.getName()+"生命值增加了"+kuijia.getFangyu()+"点血!");
}
public Fashu getFashu() {
return fashu;
}
public void setFashu(Fashu fashu) {
this.fashu = fashu;
}
//法术攻击
public void fashu(){
System.out.println("发动法术攻击!");
fashu.fashu();
System.out.println("攻击完毕!");
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getBlood() {
return blood;
}
public void setBlood(int blood) {
this.blood = blood;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Wuqi getWuqi() {
return wuqi;
}
public void setWuqi(Wuqi wuqi) {
this.wuqi = wuqi;
}
public Kuijia getKuijia() {
return kuijia;
}
public void setKuijia(Kuijia kuijia) {
this.kuijia = kuijia;
}
}
package com.rongyu.day08;
public class TestGame {
public static void main(String[] args) {
Wuqi wuqi = new Wuqi();
Kuijia kuijia = new Kuijia();
Role role = new Role();
wuqi.setName("刀");
wuqi.setShanghai(999);
kuijia.setName("狂徒铠甲");
kuijia.setFangyu(10000);
role.setWuqi(wuqi);
role.setKuijia(kuijia);
role.gongji();
role.fangyu();
role.setFashu(new Fashu() {
@Override
public void fashu() {
System.out.println("横扫千军");
}
});
role.fashu();
}
}