--------------------------------------------------------------------------------------------莫听穿林打叶声,一蓑烟雨任平生--------------------------------------------------------------------------------------------

Java笔记day15

一、static关键字补充
    父类中的静态成员可以看作是一个全局共享的
class A{
    public static int a = 10;
    public static void fun(){
        System.out.println("hello");
        }
    }


    class B extends A{
        public void fun2(){
            a = 200;
            System.out.println(a);
        }
    }


    public class ExtendsQuestion {
        public static void main(String[] args) {
            B b = new B();
            System.out.println(b.a);        //输出10
            b.fun();                        //输出hello,如果B中也有fun方法,则输出的是fun方法中的结果
            b.fun2();                       //输出200    
            System.out.println(b.a);        //输出200
        }
    }
二、多态向下转型
1、多态的前提:
    1)、要有继承的关系
    2)、子类要重写父类中的方法
    3)、要有父类的引用指向子类对象
2、多态的弊端:
    1)、多态无法使用子类特有的方法
        如果就要使用子类特有的功能,能否使用?  能
    2)、怎么使用呢?
        a、创建对应的子类并调用方法
            可以,但是不推荐,很多时候会占用堆内存空间
        b、java提我们考虑到了这一点,提供了一个技术给我们使用:向下转型
            把父类的引用强制转换成子类的引用
            子类类名 变量名 = (子类类名)父类的引用
3、多态转型
    对象之间转型的问题:
        1)、向上转型
            其实就是多态创建对象的写法
            Fu f = new Son();
        2)、向下转型
            Son s = (Son)f;
        3)、类比基本数据类型之间的强转:
                int a = 10;
                byte b = (byte)a;
        4)、向下转型的注意事项:
            要求必须是存在继承关系的
class Father{
            public void fun(){
                System.out.println("这是父类中的fun方法");
            }
        }


        class Son extends Father{
            public void fun(){
                System.out.println("这是子类中的fun方法");
            }


            public void show(){
                System.out.println("这是子类中特有的show方法");
            }
        }


        class Demo{


        }


        public class PolymorphicDemo{
            public static void main(String[] args) {
        //        Son2 son2 = new Son2();   //没有学习转型之前调用子类
        //        son2.show();


                //多态创建子类对象(向上转型)
                Father2 f = new Son2();
                f.fun();


                //多态中的向下转型
                Son2 s = (Son2)f;
                s.show();       //访问子类的show()方法


        //       Demo类与Father2类不存在继承的关系,所以不能转型
        //       Demo d = (Demo)f;
            }
        }
       
4、多态向下转型条件
    1)、要有继承关系
    2)、要有方法重写
    3)、要有父类的引用指向子类对象
三、抽象类
    1、抽象的表述:
        我们之前所说的猫,狗,猪,羊驼,熊猫等等都是动物的具体的例子,而动物本身是一个抽象的
        概念,而我们之前是将动物写成了一个类,而类又可以创建对象,但是呢,实际上抽象的东西本身应该不能
        实例化,并且动物这个概念中吃的方法,以及动物共有的方法本身也是一个不具体的方法,
        我们在今天之后,把一个不具体的功能,叫做抽象方法,而如果说一个类中包含有抽象方法的时候,
        这个类叫做抽象类。
    2、抽象类的特点:
        1)、抽象类和抽象方法要用abstract关键字修饰
            修饰类 放在class前面
                举例:
                    abstract class Animal3{}
            修饰方法 放在访问权限修饰符的后面
                举例:
                    public abstract void eat();
        2)、有抽象方法的一定是抽象类,抽象类不一定有抽象方法,具体的类中不能有抽象方法
        3)、抽象类不能被实例化
            既然不能被实例化,那写在抽象类中具体的方法怎么去调用呢?
            抽象类如果创建呢?
            利用多态的形式,通过具体的子类实例化去调用方法
        4)、如果继承抽象类是一个具体的类,要重写抽象类所有的抽象方法
            如果是一个抽象类继承抽象类,不需要重写抽象类中的方法
//定义了一个抽象类,叫Animal3
        abstract class Animal3{
            //注意:
            //  抽象方法没有方法体{},连大括号都没有,直接以分号结尾
            //抽象方法不能有主体
            //public abstract void eat(){};
            public abstract void eat();


            public void fun(){
                System.out.println("这是抽象类中的具体实现的fun方法");
            }
        }


        class Dog3 extends Animal3{
            @Override
            public void eat() {
                System.out.println("狗吃肉");
            }
        }


        abstract class Demo2 extends Animal3{


        }



        public class AbstractDemo1 {
            public static void main(String[] args) {
                //Error:(46, 21) java: com.shujia.wyh.day16.Animal3是抽象的; 无法实例化
                //Animal3 a = new Animal3();


                //使用抽象多态的形式创建
                Animal3 a = new Dog3();
                a.eat();
                a.fun();
            }
        }
    3、抽象类举例
/*
            在抽象的动物类中定义两个抽象方法。吃饭和睡觉。
        */


        abstract class Animal4{
            //定义一个抽象方法吃饭,不给出具体实现
            public abstract void eat();


            //定义一个抽象方法睡觉,不给出具体实现
            public abstract void sleep();
        }


        class Dog4 extends Animal4{
            @Override
            public void eat() {
                System.out.println("狗吃肉");
            }


            @Override
            public void sleep() {
                System.out.println("狗侧着睡");
            }


            public void lookDoor(){
                System.out.println("看门");
            }
        }


        class Cat4 extends Animal4{


            @Override
            public void eat() {
                System.out.println("猫吃鱼");
            }


            @Override
            public void sleep() {
                System.out.println("猫趴着睡");
            }
        }



        public class AbstractTest1 {
            public static void main(String[] args) {
                //使用抽象多态创建第一个对象
                Animal4 a = new Dog4();
                a.eat();
                a.sleep();
                //a.lookDoor();
                Dog4 d = (Dog4)a;
                d.lookDoor();


                //使用抽象多态创建第二个对象
                Animal4 a2 = new Cat4();
                a2.eat();
                a2.sleep();
            }
        }
     
    4、抽象类的成员特点
        抽象类的成员特点
            成员变量
                可以是变量,也可以是常量
            构造方法
                有构造方法,但是我们上一个程序中总结出抽象类不能实例化,那构造的意义是
                什么呢?要想初始化子类,就必须先初始化父类,在继承的关系中有用
            成员方法
                可以有抽象方法 限定子类必须完成某些动作
                也可以有非抽象方法 提高代码复用性
abstract class Animal5{
            public int a;
            public final int b = 20;


            Animal5(){
                a = 20;
                System.out.println(a);
            }
        }


        class Dog5 extends Animal5{


        }


        public class AbstractDemo2 {
            public static void main(String[] args) {
                Dog5 dog5 = new Dog5();
            }
        }
   5、问题
        一个类如果没有抽象方法,可不可以定义为抽象类?
        可以
        如果可以,有什么意义?
        橙汁,水,牛奶等这些东西用共同的特点,我们把这些相同的行为概念归结成一个类
        假设叫做液体。
        至于后面有没有抽象方法,取决于这些东西有没有相同的行为,只是说有着相同的本质。没有
        实际的共同的行为,也可不写抽象方法,也是合情合理的。
            1、抽象类中可以没有抽象方法
            2、抽象类不能被实例化
        抽象类中可以存在哪些关键字?abstract关键不能和哪些关键字共存?
            private     不能共存
            final       不能共存
            static      不能共存
        java中所有类都有一个共同的父类:Object
abstract class Liquid{
        //    //java中所有类都有一个共同的父类:Object
        //    Liquid(){
        //        super();
        //    }
            //abstract关键字可以和public关键字共存
            public abstract void show();


            //abstract关键字和private关键字冲突
        //    private abstract void show1();


            //非法的修饰符组合: abstract和final
        //    final abstract void show2();


            //非法的修饰符组合: abstract和static
        //    static abstract void show3();


            public static void show4(){
                System.out.println("这是父类中的静态方法");
            }


        }


        class Milk extends Liquid{


        }


        public class AbstarctSiKao {
            public static void main(String[] args) {
                //Liquid l = new Liquid();      //报错,抽象类不能被实例化
                //Liquid l = new Milk();
                Liquid.show4();
            }
        }
四、面向对象综合举例
    /*
    猫狗案例
        具体事物:猫,狗
        共性:姓名,年龄,吃饭
    分析:从具体分析到抽象的过程
        猫:Cat
            成员变量:姓名,年龄
            构造方法:无参构造,有参构造
            成员方法:吃饭(猫吃鱼)
        狗:Dog
            成员变量:姓名,年龄
            构造方法:无参构造,有参构造
            成员方法:吃饭(狗吃肉)
        通过分析我们发现,两个类存在相同的内容,所以提取出一个抽象类:Animal6
        抽象动物类:
            成员变量:姓名,年龄
            构造方法:无参构造,有参构造
            成员方法:吃饭(该方法是抽象的,没有具体的实现)
    */
    具体实现:
 //定义一个抽象动物类
        abstract class Animal6 {
            //姓名
            private String name;
            //年龄
            private int age;


            //无参构造
            Animal6() {


            }


            //有参构造
            Animal6(String name, int age) {
                this.name = name;
                this.age = age;
            }


            public String getName() {
                return name;
            }


            public void setName(String name) {
                this.name = name;
            }


            public int getAge() {
                return age;
            }


            public void setAge(int age) {
                this.age = age;
            }


            //show方法,输出所有的成员变量值
            public void show() {
                System.out.println("姓名:" + this.name + ",年龄:" + this.age);
            }


            //吃饭的抽象方法
            public abstract void eat();
        }


        class Dog6 extends Animal6 {


            Dog6() {


            }


            Dog6(String name, int age) {
                super(name, age);
            }


            @Override
            public void eat() {
                System.out.println("狗吃肉");
            }
        }


        class Cat6 extends Animal6 {


            Cat6() {


            }


            Cat6(String name, int age) {
                super(name, age);
            }


            @Override
            public void eat() {
                System.out.println("猫吃鱼");
            }
        }


        public class AbstractTest2 {
            public static void main(String[] args) {
                //使用多态创建第一个对象
                Animal6 a = new Dog6("小白", 3);
                a.show();
                a.eat();
                //创建第二个对象,使用公共的getXxx和setXxx进行赋值
                Animal6 a2 = new Dog6();
                a2.setName("大黄");
                a2.setAge(4);
                a2.show();
                a2.eat();
                //创建第三个对象
                Animal6 a3 = new Cat6("小黑",2);
                a3.show();
                a3.eat();
            }
        }
       
posted @ 2021-12-11 22:51  等你回眸一笑  阅读(63)  评论(0)    收藏  举报