特性之多态
一,概念
形象点说就是同一个行为由不同的人或事物执行所产生的不同的状态
二,实现条件
- 必须是在继承体系下
- 派生类必须对基类中的方法进行重写
- 必须是通过基类的引用调用重写的方法
三,代码实现(以不同的人群购票为例)
假设三个常见群体
- 成人全票
- 学生半票
- 军人免票
1.编写买票基类
public class BuyTicket {
public String name;
public BuyTicket(String name) {
this.name = name;
}
public void Ticket(){
System.out.println("购票");
}
}
2.依次编写成人,学生,军人买票的派生类,并重写买票的方法
//成人买票派生类
public class Adult extends BuyTicket{
public Adult(String name) {
super(name);
}
@Override
public void Ticket(){
System.out.println("成人买全票!");
}
}
//学生买票派生类
public class Student extends BuyTicket{
public Student(String name) {
super(name);
}
@Override
public void Ticket(){
System.out.println("学生买半价票!");
}
}
//军人买票的派生类
public class Soldier extends BuyTicket{
public Soldier(String name) {
super(name);
}
@Override
public void Ticket(){
System.out.println("军人免票!");
}
}
3.编写买票的测试方法
public class TestBuyTicket {
public static void Ticket(BuyTicket a){
a.Ticket();
}
public static void main(String[] args) {
Adult A = new Adult("成人");
Student B = new Student("学生");
Soldier C = new Soldier("军人");
A.Ticket();
B.Ticket();
C.Ticket();
}
}
4.最终的运行及结果
总结:
通过派生类new一个对象出来,通过这个对象调用相应的方法
四,重写与重载的主要区别
重写的主要特征
- 方法重写前后名字要一致,参数列表要一致
- 返回类型与被重写方法的返回类型可以不相同,但是必须是基类返回值的派生类(和jdk版本有关系)
- 访问权限不能比基类中被重写的方法的访问权限更低
- 基类的成员方法只能被他的子类重写
- 被final,static修饰的方法不能被重写
- 构造方法不能被重写
- 在同一个包中,可以重写除被private和final修饰的方法
- 在不同包中,只能重新被public,protected修饰的非final方法
- 采用override可以更加规范的重写方法
重写和重载
五,向上转型
向上转型:实际就是创建一个子类对象,将其当成基类对象来使用。
语法格式:基类类型 对象名 = new 子类类型()
BuyTicket buyTicket = new Student("学生1");
子类对象是一个基类对象,即可以将一个子类对象当成基类对象来应用。因此:向上转型是安全的,因为是从小范围向大范围的转换(可以说学生是一个群体,但是不能说群体就是学生,也包含其他群体,例如教师,军人,医生等等)
优点:
减少一些重复的代码
对象实例化的时候可以根据不同需求实例化不同的对象
特性:
- 不能调用到子类的特有方法
六,向下转型
将一个子类对象经过向上转型之后当成基类方法使用,再无法调用子类的方法,但有时候可能需要调用子类特有的方法,此时:将父类引用再还原为子类对象即可,即向下转换
Student s1 = new Student("学生2");
BuyTicket a1 = (BuyTicket) s1;
缺点:如果由大到小的范围不正确会抛出异常,向下转型也极为不安全
Java中为了提高向下转型的安全性,引入了 instanceof ,如果该表达式为true,则可以安全转换
特性之抽象
一,概念
如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类
二,语法
在Java中,一个类如果被 abstract 修饰类称为抽象类,抽象类中被 abstract 修饰的方法称为抽象方法,抽象方法不用给出具体的实现体
//被abstract修饰的类是抽象类
public abstract class Animal {
//被abstract修饰的方法是从抽象方法,不用给出方法体
abstract public void eat();
abstract void sleep();
//抽象类也可以给出普通方法和属性
public void method(){
System.out.println("我是抽象类的普通方法!");
}
public String name;
}
三,抽象类的特性
1.不能实例化对象
2.抽象方法不能是private的(在抽象类中默认的访问限定符是public)
3.抽象方法不能被final和static修饰(抽象方法需要被子类重写)
4.抽象类必须被继承,并且继承后子类要重写父类中的抽象方法,否则子类也是抽象类,必须要 使用 abstract修饰
public class Dog extends Animal{
public void eat(){
System.out.println("啃骨头!");
}
public void sleep(){
System.out.println("汪汪队睡大觉!");
}
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat();
dog.sleep();
}
}
5.抽象类中不一定有抽象方法,但是有抽象方法的一定是抽象类
四,抽象类的作用
如果想要在抽象类中实例化对象,必须在子类中进行,所以让子类继承此抽象类,并且要在子类中重写所有的抽象方法