多态
概念
同一类的不同子类形态。可以声明,父类对象变量保存子类对象的形式
现实生活中存在很多多态的例子。 例如:水在100摄氏度的高温下是气体,在常温下是液体,在0摄氏度以下是固体。这里的多态是指一个对象具有多种形态 OOP中的多态与之类似。 同一个引用类型,使用不同的实例可以执行不同的操作,即父类引用子类对象——向上转型。
java中的多态理解为另一种数据类型转换
//宠物类
public class Pet {
public String name = "无名氏"; // 宠物昵称
public Pet(String name){
this.name=name;
}
public void eat(){ }
}
//狗类
public class Dog extends Pet{
public Dog(String name) {
super(name);
}
@Override
public void eat() {
System.out.println("狗"+name+"吃骨头");
}
}
//猫
public class Cat extends Pet{
public Cat(String name) {
super(name);
}
@Override
public void eat() {
System.out.println("猫"+name+"吃鱼");
}
}
//主人类
public class Master {
public void food(Pet pet) {
pet.eat();
}
}
//测试类
public class Test {
public static void main(String[] args) {
Master m=new Master();//主人对象
//向上转型
//声明父类变量 保存子类对象
//jvm在调用方法时会自动根据实际对象调用方法
Pet dog=new Dog("大黄");
Pet cat=new Cat("花花");
m.food(dog);
m.food(cat);
}
}
1、必须发生继承
只有发生继承多个对象才能进行联系
2、向上转型
声明父类变量保存子类对象,这样才能使用同一个变量表示多个不同相关联的变量,jvm在进行使用时会根据不同对象进行使用
子类对象存储至父类变量时,与子类一同创建的父类对象可以直接赋值,但子类中额外的属性与方法在声明的父类变量中并没有进行声明,父类变量会帮子类对象进行存储但是,不能使用
向上转型
声明父类变量保存子类对象(类似于自动类型转换)
声明子类变量保存父类对象(类似于强制类型转换)
1、多态发生的条件继承、向上转型、重写
2、只能使用子类重写父类的方法以及父类特有的属性与方法
3、向下转向成功的前提:曾经发生过向上转型
多态的优点与缺点
优点:提高了代码的维护性与扩展性
缺点:只能在继承后的子类中使用,并且只能使用子类重写父类的方法而不能使用子类特有的方法
抽象类
在java开发过程中存在不能拥有具体对象的类,这些类同性时可以作为其余类的父类,因为可以代表多个类,所以如果可以创建对象,那么创建对象的类别很难划分,这个时候就需要使用抽象类关键字abstract进行修饰,将使用abstract修饰的类称之为抽象类,同理。使用abstract修饰的方法称之为抽象方法
抽象类与抽象方法的特点
1、 抽象方法没有方法体连{}都没有
抽象方法就是不知道怎么实现的方法,但是我们可以书写除方法体外的代码,所以抽象方法将方法体省略其余正常书写,由子类进行方法体的完善
//宠物类
public abstract class Pet {
public String name = "无名氏"; // 宠物昵称
public Pet(String name){
this.name=name;
}
public abstract void eat();
}
2、子类继承后抽象方法必须实现
//老鼠类
public class Mouse extends Pet{
public Mouse(String name) {
super(name);
}
@Override
public void eat() {
System.out.println("老鼠"+name+"吃大米");
}
}
4、抽象类不一定有抽象方法
接口
接口在Java中是最重要的概念之一,它可以被理解为一种特殊的类,是由全局常量和公共的抽象方法所组成。 需要注意的是,在接口中的抽象方法必须定义为public访问权限,这是不可更改的。
接口其实本质上已经不是类了
接口不是一个类
2、接口中的所有成员变量都是public static final
3、接口中的方法都是抽象方法,接口中的方法会自动使用public abstract修饰。
在接口中不能写方法体,但是声明方法时可以直接使用 返回值类型 方法名(参数列表);的形式
4、一个类可以同时实现多个接口。
接口不是类无需遵循类的单继承而且接口使用的是实现implements 所以不是继承
5、实现类必须实现接口中的所有方法。
如果实现类中存在没有实现的方法那么这个类应为抽象类,不能被使用
6、接口可以继承接口(接口可以继承多个接口)
接口不是类所以无需遵循java中类的单继承
7、接口中不能出现静态方法,因为absctrant 不能修饰static static的方法是不能被继承的
//接口
public interface BossWork {
//接口中只能书写全局静态常量与静态方法
//所有方法默认使用 public abstract进行修饰(如果没写会默认添加)
public void one();
abstract void two();
void three();
public abstract void four();
//接口可以理解为老板安排的工作
}
//另一个接口
public interface BossWork2 {
void add();
}
//接口的实现
//通过implements关键字将接口进行关联
//接口不是类所以可以多实现
public class My implements BossWork,BossWork2{
//实现类可以被使用的情况
//1、实现了所有接口的抽象方法
//2、将实现类当做抽象类创建子类继承重写所有抽象方法
@Override
public void one() {}
@Override
public void two() {}
@Override
public void three() {}
@Override
public void four() {}
@Override
public void add() {}
}
/接口不是类所以可以多继承
//现在BossAllWork这个接口拥有BossWork,BossWork2这两个接口中所有抽象方法
public interface BossAllWork extends BossWork,BossWork2{
}
接口与抽象类在实际开发过程中都由程序员进行编写
接口的作用
1、在程序开发初期对程序需要书写的功能做一个全面的定义
2、便于开发与维护
当程序书写完毕,进行维护时,可以通过接口快速了解相应类具体功能
抽象类与接口的区别
相同:
1、都可以书写抽象方法
不同:
2、抽象类可以书写任意属性,接口中只能书写全局静态常量
3、抽象类中可以定义构造方法(系统会默认添加无参构造方法),接口中不能定义构造方法(系统不会添加无参构造方法)
4、抽象类使用子类继承重写的方式实现抽象方法,拘泥于java类的单继承,接口使用实现类实现的方式不是类的继承所以可以多实现,接口不是类,所以接口与接口之间可以多继承
练习:
书写员工类,拥有属性生日月份,工资,拥有方法计算当月工资方法
拥有子类
销售员工类:工资由提成率x销售额组成
底薪销售员工类:工资由底薪+提成率x销售额组成
固定工资员工类:工资由固定薪资组成
小时工类:薪资由小时工资x月工作小时数组成
乞丐类:薪资天定范围在(0~10000)
所有子类重写计算薪资方法计算当月工资,要求添加员工福利(生日当月工资额外+100)
将之前书写的atm类书写接口并实现
注意:本文归作者所有,未经作者允许,不得转载