抽象和继承的多态
抽象
abstract关键字用来修饰关键方法和修饰抽象类。为什么会产生抽象类呢,那是因为在代码的开发过程种,子类的种类越来越多,也越来越具体,慢慢的基本不需要使用父类的具体实现(也就是不需要new 父类后,来使用父类,而是只是把所有子类用的东西抽象出来,放到父类种,具体使用子类的实现,来实现具体的功能,就像现在没有人会new Oject()没人会直接使用Object类一样)。
抽象类
虽然不能new 父类,但是需要保留父类的构造方法,因为在子类实例化的时候需要先去调用父类的构造方。
package com.mystudy;
/**
* @author yongchaoliu
* @create 2020-12-30 10:47
*/
public class TestAbstract {
public static void main(String[] args) {
HumanA a=new HumanA("张三",12);
System.out.println(a);
a.updateAge();
System.out.println(a);
}
}
abstract class Personss{
protected Integer age;
protected String name;
public Personss (){
}
public Personss(String name,Integer age){
this.age=age;
this.name=name;
}
public void eat(){
System.out.println("person eat");
}
@Override
public String toString() {
return "Personss{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
class HumanA extends Personss{
public HumanA() {
}
public HumanA(String name, Integer age) {
super(name, age);
}
public Integer updateAge(){
return this.age=11;
}
}
抽象方法
用abstract修饰的方法就是抽象方法
1.抽象方法所在的类一定是抽象类,反之,抽象类中不一定含有抽象方法
为什么抽象方法所在的类一定是抽象类呢? :首相我们前面说过了,抽象类是不用来实例化直接使用的,如果抽象方法所在的类不是抽象类,那就是需要实例化的(比如普通子类中含有抽象方法,那么实例化子类的时候,当调用抽象方法的时候,没有方法体,就会有问题,所以要么抽象方法必须在抽象类中,并且普通子列重写抽象方法,要么子类也是抽象类)
abstract class Person{
protected Integer age;
protected String name;
**************
/**其他普通的方法**/
**************
//抽象方法,没有方法体
public abstract String walk ();
}
***************子类重写抽象方法****************
class Human extends Person{
**************
/**其他普通的方法**/
**************
//子类重写抽象方法
@Override
public String walk() {
return "HumanA_walk";
}
}
********子类也是抽象类***********
abstract class Human extends Person{
**************
/**其他普通的方法**/
**************
public abstract void run();
}
继承的多态
class Person_A{
public void eat(){
System.out.println("人吃饭");
}
public void walk(){
System.out.println("人走路");
}
}
class Man_A extends Person_A{
@Override
public void eat() {
System.out.println("男人爱吃肉");
}
@Override
public void walk(){
System.out.println("男人走得快但是不爱逛街");
}
public String EarnMoney(){
return "男人要挣钱";
}
}
class Women_A extends Person_A{
@Override
public void eat() {
System.out.println("女人也爱吃肉,但是要减肥");
}
@Override
public void walk() {
System.out.println("女人爱逛街");
}
public String birthdat(){
return " A baby";
}
可以看出使用父类的引用指向子对象时 (Person_A man=new Man_A())只能调用父类中的方法,可以看到调用子类中的独有方法是编译不过去的,那么问题来了,在我们是用多态的时候,我们传一个子类到形参是一个父类的方法是,无法调用子类独有的方法,那么多态就毫无意义了不是吗,我们可以强转一下接了调用相应的方法了
public class TestIsInstanceof {
public static void main(String[] args) {
Person_A man=new Man_A();
Person_A women =new Women_A();
test(man);
}
public static void test(Person_A person){
//假设我们默认传入的就是man,就是要调用
Man_A m=(Man_A) person;
System.out.println(m.EarnMoney());
}
}
但是这存在一个问题,如果我传入一个women呢 这个时候强转就会报错。
instanceof 关键字
所以就需要用到instanceof 关键字,该关键字表示是不是类的一个实例,或者说是不是该类或者是不是该类的子类。是就可以可以强转了。(需要注意的是women instanceof women 是false的)
public class TestIsInstanceof {
public static void main(String[] args) {
Person_A man=new Man_A();
Person_A women =new Women_A();
test(man);
test(women);
}
public static void test(Person_A person){
//假设我们默认传入的就是man,就是要调用
Object o=null;
if(person instanceof Women_A){
Women_A w=(Women_A)person;
o= w.birth();
}
if(person instanceof Man_A){
Man_A m=(Man_A)person;
o= m.EarnMoney();
}
System.out.println(o.toString());
}
}
关于强转
在我们不同的类型的相互转换的时候,
**1.**低精度的可以自动转换成高精度,
**2.**高精度不能自动转换为低精度,需要用到强转
关于子类和父类的互相转换
1.子类可以自动转换为父类(父类的引用指向子类的实例)
2.父类不可以自动转换为子类
3.父类的引用指向子类对象后,可以强转回子类
4.子类之间不能互相转换。
为什么回存在这样的现象呢?说一下我的理解 ,我们从实际的使用场景中就能理解了。
1.子类可以自动转换为父类(父类的引用指向子类的实例): 实际场景中我们需要使用到多态,这就需要在父类是形参的视情况下,允许我们传入子类实例
2.父类不可以自动转换为子类: 父类转换为子类以后,当我们调用子类中特有的方法是肯定会报错,因为父类中没有子类特有的方法。
3.父类的引用指向子类对象后,可以强转回子类: 子类转为父类以后,相当于我只调用子类的部分功能,不会产生任何异常,当想转会子类时再转回来就是了,自己转自己而已。
4.子类之间不能互相转换: 本来就不是父子关系,转个毛线(父债子还,有父债大街随便抓个人还吗,哈哈哈哈)
本文地址:https://blog.csdn.net/Insect_boy/article/details/111952326
上一篇: 模板——类型萃取
下一篇: DeDecms迁移数据提示dede怎么办