Java基础知识 11(面向对象之多态,向下转型,抽象类abstract关键字)

Java基础知识

面向对象—多态
面向对象的三大特征:封装(类),继承(extends),多态
多态:指的是一种事物在不同时期,所表现的不同状态。
多态的前提:要有继承,如果没有继承,多态就无从谈起。多态要有方法重写,当然不重写对于语法上来说不报错,但是就失去了多态的意义。
案例程序分析1:
public class Mytest {
    public static void main(String[] args) {
        //面向对象的三大特征;封装(类) 继承(extends)多态
        //多态:指的是一种事物,在不同时期,所表现出的不同状态。
        //多态的前提:要有继承,如果没有继承多态就无从谈起。
        //多态要有方法重写,当然不重写,语法上来说不报错,但是失去了多态的意义。
        //父类引用指向子类对象。
        Cat cat = new Cat();
        cat.eat();
        //多态:父类引用,指向子类对象
        Animal an = new Cat();
        an.eat();
    }
}
class Animal{
    public void eat(){
        System.out.println("吃饭");
    }
}
class Cat extends Animal{
    @Override
    public void eat() {
        //super.eat();
        System.out.println("猫吃小鱼干");
    }
}
1.多态:父类引用指向子类对象,采用多态的形式,去访问成员变量,访问的是父类。
	成员变量:编译看左边,运行看左边。
2.多态形式去访问构造方法:创建子类对象的时候,会调用父类的构造方法,对父类的数据进行初始化。
	***用多态的时候,先调用父类的构造方法,再调用子类的构造方法***。
3.多态的形式,访问成员方法的特点,如果子类没有重写父类的方法,就以父类的方法为准,如果子类重写了父类的方     法,那么运行时,就以子类重写过的为准。
	成员方法:编译看左边,运行看右边。
案例程序分析2:
public class Mytest {
    public static void main(String[] args) {
        //多态:父类引用,指向子类对象
        Fu an = new Zi();
        //int num = ((Zi) an).num;
        System.out.println(an.num);//100 采用多态的形式,去访问成员变量,访问的是父类的成员变量
        System.out.println(((Zi) an).num);//200
        System.out.println("-------------");
        //多态的形式,访问成员方法的特点,
        // 如果子类没有重写父类的方法,就以父类的方法为准,
        // 如果子类重写了父类的方法,那么运行时,会以子类重写过后的为准。
        an.show();
        //静态方法
        an.fujingtai();
        Fu.fujingtai();
    }
}
class Fu{
    int num=100;
    public Fu(){
        System.out.println("父类的构造方法执行了");//1
    }
    public void show(){
        System.out.println("父类的show方法执行了");
    }
    public static void fujingtai(){
        System.out.println("父类的静态方法执行了");//4.5
    }
}
class Zi extends Fu{
    int num=200;
    int aa=500;
    public Zi(){
        System.out.println("子类的构造方法执行了");//2
    }
    @Override
    public void show() {
        //super.show();
        System.out.println("子类的show方法执行了");//3
    }
}
多态的好处:多态的好处:提高代码的复用性a:提高了代码的维护性(继承保证)
	b:提高了代码的扩展性(由多态保证)
案例程序分析3:
public class Mytest {
    public static void main(String[] args) {
        //多态的好处:提高代码的复用性a:提高了代码的维护性(继承保证)
        //	b:提高了代码的扩展性(由多态保证)
        Cat cat = new Cat();
        MyUtils.testEat(cat);
        Dog dog = new Dog();
        MyUtils.testEat(dog);
        Tiger tiger = new Tiger();
        MyUtils.testEat(tiger);
        Rabbit rabbit = new Rabbit();
        MyUtils.testEat(rabbit);
        Panda panda = new Panda();
        MyUtils.testEat(panda);
    }
}
class Animal{
    public void eat(){
        System.out.println("吃饭");
    }
}
class Cat extends Animal{
    @Override
    public void eat() {
        //super.eat();
        System.out.println("猫吃老鼠");
    }
}
class Dog extends Animal{
    @Override
    public void eat() {
        //super.eat();
        System.out.println("狗吃骨头");
    }
}
class Panda extends Animal{
    @Override
    public void eat() {
        //super.eat();
        System.out.println("熊猫吃竹子");
    }
}
class Rabbit extends Animal{
    @Override
    public void eat() {
        //super.eat();
        System.out.println("小白兔吃草");
    }
}
class Tiger extends Animal{
    @Override
    public void eat() {
        //super.eat();
        System.out.println("老虎吃肉");
    }
}
----------------------------------------------
public class MyUtils {
    //如果你通过方法重载,来设计这个工具类。
    // 扩展性不好。因为没增加一种动物。你就得在工具类中提供一个重载方法。
    //私有构造
    private MyUtils(){
    }
    public static void testEat(Animal an){
        //Animal an=new Cat()
        //Animal an=dog//
        // Animal an = tiger
        an.eat();
    }
    /*  public static void testEat(Cat cat) {
        cat.eat();
    }
    public static void testEat(Dog dog) {
        dog.eat();
    }
    public static void testEat(Tiger tiger) {
        tiger.eat();
    }
    public static void testEat(Rabbit rabbit) {
        rabbit.eat();
    }*/
}
向下转型
多态的弊端:不能直接调用子类特有的功能。
多态的形式不能直接调用子类特有的功能,如果要调用子类特有的功能,即向下转型。
        向上转型:把子类型,转换成父类型。多态就是向上转型。
案例程序分析4:
public class Mytest {
    public static void main(String[] args) {
        //多态的弊端,不能直接调用子类特有的功能
        Fu fu = new Zi();
        fu.show();
        //多态的形式不能调用子类特有的功能
        //如果我们要调用子类特有的功能,需要采用向下转型。
        Zi zi=(Zi) fu;//向下转型
        zi.method();
        //向上转型:把子类型,转换成父类型。多态就是向上转型.
    }
}
class Fu{
    public void show(){
        System.out.println("父类的show方法");
    }
}
class Zi extends Fu{
    @Override
    public void show() {
        //super.show();
        System.out.println("我重写了父类的show方法");
    }
    public void method(){
        System.out.println("这是子类特有的method方法");
    }
}
案例程序分析5:
public class Mytest {
    public static void main(String[] args) {
        Animal an = new Cat();//多态,向上转型
        an.eat();
        Cat cat = (Cat) an;//向下转型
        cat.catchMouse();
        Animal an1 = new Dog();//多态,向上转型
        an1.eat();
        Dog dog = (Dog) an1;//向下转型
        dog.lookDoor();
    }
}
class Animal{
    public void eat(){
        System.out.println("吃饭");
    }
}
class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }
    public void lookDoor(){
        System.out.println("狗看门");
    }
}
class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
    public void catchMouse(){
        System.out.println("猫抓老鼠");
    }
}
案例程序分析6:
public class MyTest {
    public static void main(String[] args) {
        Father father = new Son();//采用多态的形式去访问成员变量,访问的是父类
        System.out.println(father.num);  //100
        father.show();
        //访问子类的成员变量,访问子类特有的功能,采用向下转型
        Son son= (Son) father;
        System.out.println(son.num); //50
        son.hehe();
    }
}
class Father{
    int num=100;
    public void show(){
        System.out.println("父类 show 方法");
    }
}
class Son extends Father{
    int num=50;
    @Override
    public void show() {
        System.out.println("子类 show 方法");
    }
    public void hehe(){
        System.out.println("子类特有的方法");
    }
}

多态内存图:
在这里插入图片描述

练习题:案例程序分析7:
class A {
	public void show() {
		show2();
	}
	public void show2() {
		System.out.println("我");
	}
}
class B extends A {
	public void show2() {
		System.out.println("爱");
	}
}
class C extends B {
	public void show() {
		super.show();
	}
	public void show2() {
		System.out.println("你");
	}
}
public class DuoTaiTest4 {
		public static void main(String[] args) {
			A a = new B();
			a.show();//爱
			B b = new C();
			b.show();//你
		}
	}
抽象类
abstract关键字:
抽象类:抽象出来,不需要给出功能的具体实现,而是由子类根据自身的差异性,对这个功能进行具体的实现。
一旦一个类中,有了抽象方法该类必须为抽象类。抽象类:不能直接创建对象。
父类中的抽象方法,是强制子类必须重写:
abstract class Animal{
    public abstract void eat();——————>父类给个声明
}
案例程序分析8:
public class Mytest {
    public static void main(String[] args) {
        //抽象类,不能直接创建对象
        Animal cat = new Cat();
        cat.eat();
        cat.sleep();
        Animal dog = new Dog();
        dog.eat();
        dog.sleep();
    }
}
abstract class Animal{
    //抽象的父类,在父类中只需要给出一个声明,由子类去重写父类的方法,实现需要的功能。
    public abstract void eat();
    public abstract void sleep();
}
class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫不喜欢吃饭,他喜欢捉老鼠");
    }

    @Override
    public void sleep() {
        System.out.println("猫喜欢在白天睡觉,晚上出来活动");
    }
}
class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗不喜欢吃饭,它喜欢吃骨头");
    }

    @Override
    public void sleep()  {
        System.out.println("狗整天都在睡觉");
    }
}
父类把所有子类的共享内容向上抽取出来,但是父类不知道子类对于共性功能的具体实现,所以父类只需要给出功能的声明,而不需要给出功能的具体实现,那功能的具体实现,应该交给子类按照自身的需求和差异,去做具体的实现。
一个抽象类中可以不用定义抽象方法。
一旦一个类中定义了抽象方法,此类必须为抽象类
抽象类的子类:要么是抽象类,要么重写抽象类中的所有抽象方法
案例程序分析9:
public class Mytest {
    public static void main(String[] args) {
        EE ee = new EE();
        ee.BB();
        ee.DD();
        ee.show();
    }
}
abstract class BB{
    public abstract void  show();
    public abstract void BB();
}
abstract class DD extends BB{
    public abstract void DD();
}
class EE extends DD{
    @Override
    public void show() {
        System.out.println("继承父类的show方法");
    }

    @Override
    public void BB() {
        System.out.println("继承父类的BB方法");
    }

    @Override
    public void DD() {
        System.out.println("继承父类的DD方法");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值