多态和接口
多态
什么是多态
同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果,简单来说就是:一个事务在不同的情况下有着不同形态(基类的引用指向子类的对象)
实现多态的三个条件
- 继承
- 方法的重写
- 父类引用指向子类对象
多态的使用
// 父类
public class Fu {
public void info() {
System.out.println("父类的方法");
}
public void infoFu(){
System.out.println("父类的独有方法");
}
}
// 子类
public class Zi extends Fu {
@Override //重写info方法
public void info() {
System.out.println("子类的方法");
}
}
// 测试类
public class Test {
public static void main(String[] args) {
Fu fu = new Zi();
// new的是谁调用的就是谁里面的方法
fu.info();
fu.infoFu();
// 也就是说这个对象具有子类形态和父类形态
}
}
// 运行结果
子类的方法
父类的独有方法
多态的复杂使用
使用多态实现主人溜宠物
// 父类 动物类
public class Pet {
private String name;
private String color;
/**
* @return 获取 name
*/
public String getName() {
return name;
}
/**
* 设置 name
*
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* @return 获取 color
*/
public String getColor() {
return color;
}
/**
* 设置 color
*
* @param color
*/
public void setColor(String color) {
this.color = color;
}
public void info() {
}
}
// 子类 猫类
public class Cat extends Pet{
@Override
public void info() {
System.out.println("我叫"+this.getName()+",我的颜色是"+this.getColor()+",我是猫类");
}
}
// 子类 狗类
public class Dog extends Pet {
@Override
public void info() {
System.out.println("我叫" + this.getName() + ",我的颜色是" + this.getColor() + ",我是狗类");
}
}
// 主人
public class Master {
public void liu(Pet pet){
pet.info();
}
}
// 测试类
public class Test {
public static void main(String[] args) {
Master master = new Master();
Pet dog = new Dog();
dog.setName("旺财");
dog.setColor("黑色");
master.liu(dog);
Pet cat = new Cat();
cat.setName("肥波");
cat.setColor("白色");
master.liu(cat);
}
}
//控制台运行结果
我叫旺财,我的颜色是黑色,我是狗类
我叫肥波,我的颜色是白色,我是猫类
向上转型和向下转型
向上转型(子类转向父类)
Pet dog = new Dog();
向上转型的时候我们无法调用子类独有的方法(因为我们创建的类型是父类,所以无法调用子类独有的属性和方法)
向下转型(父类转向子类)
Pet dog = new Dog();
Dog dog2 = (Dog)dog;
向下转型必须进行强制类型转换,向下转型后的对象可以调用父类的独有的属性和方法也可以调用子类独有的属性和方法
抽象类和抽象方法
//抽象类
public abstract class Action {
//抽象方法
public abstract void doSomething();
}
//抽象类的实现
public class Test extends Action{
@Override
public void doSomething() {
}
}
抽象类
抽象类的特点
- 使用abstract关键字创建
- 抽象类不能new出来,也就是说不能被实例化,只能靠子类去实现它
- 抽象类中可以有普通方法,但抽象方法必须在抽象类中
- 抽象类具有构造方法
- 利于代码的维护和重用
抽象方法
抽象方法的特点
- 使用abstract关键字创建
- 抽象方法必须在抽象类中
- 抽象方法就是只有方法名字,没有具体的实现
接口
普通类和抽象类和接口的区别
- 普通类
- 只有具体的实现
- 抽象类
- 具体实现和规范(抽象方法)都有
- 接口
- 只有规范(抽象方法),自己无法去写方法
什么是接口
- 接口就是规范,定义了一组规则
- 接口的本质是契约,也就是说定义好之后就必须去遵守
- 接口是OOP(面向对象)的精髓,是对对象的抽象,最能体现这一点的就是接口
使用代码实现接口
//定义一个接口
public interface UserService {
//接口中的方法都是使用public、abstract两个关键字修饰的
void run();
void add(String name);
void del(String name);
void update(String name);
void query(String name);
}
//接口的实现
public class UserServiceImpl implements UserService{
@Override
public void run() {
}
@Override
public void add(String name) {
}
@Override
public void del(String name) {
}
@Override
public void update(String name) {
}
@Override
public void query(String name) {
}
}
在Java中一个类可以同时实现多个接口(简单的来说就是可以继承多个接口)
//定义一个接口
public interface TimeService {
void timer();
}
//定义一个接口
public interface UserService {
//接口中的方法都是使用public、abstract两个关键字修饰的
void run();
void add(String name);
void del(String name);
void update(String name);
void query(String name);
}
//接口的实现
public class UserServiceImpl implements UserService,TimeService{
@Override
public void run() {
}
@Override
public void add(String name) {
}
@Override
public void del(String name) {
}
@Override
public void update(String name) {
}
@Override
public void query(String name) {
}
@Override
public void timer() {
}
}
接口中的关键字
- interface
- 定义一个接口的关键字
- implements
- 实现一个接口的关键字(伪继承)
注意事项
- 接口中定义的方法都是使用public、abstract两个关键字修饰的
- 接口中定义的属性都是使用public、static、final三个关键字修饰的,也就是说在接口中定义的属性都是常量
- 接口不能被实例化,接口中没有构造方法
- 实现接口必须重写里面的方法
接口的作用
接口的作用就是把使用接口的人和实现接口的人分开,实现接口的人不必要关心谁去使用,而使用接口的人也不用关心谁实现的接口,由接口将他们联系在一起。