zoukankan      html  css  js  c++  java
  • 多态、抽象类、接口_DAY09

    1:多态(掌握)

       (1)多态概念:一种事物的多种形态

       (2)体现:父类的引用指向其子类的实例对象;接口的引用指向其实现类的实例对象

       (3)特点:

              成员方法:编译看左边,运行看右边

                    运行:子类重写的方法运行

                    编译:父类的引用类型必须有该方法

              成员变量:编译看左边,运行看左边

                  运行:访问的为父类的属性

                   编译:父类的引用类型必须有该属性

                 总结:只有在方法调用的时候,才会判断子类是否重写,重写调用子类方法。其他情况均看父类类型

                 记忆方法:方法运行看右边,其他看左边

               例子:

    /*
        多态:
            一种事物的多种形态
        前提:
            具有继承关系
        特点:
            方法:编译看左边,运行看右边
                运行:子类重写的方法运行
                编译:父类的引用类型必须有该方法        
            变量:编译看左边,运行看左边
                运行:访问的为父类的属性
                编译:父类的引用类型必须有该属性
            只有在方法调用的时候,才会判断子类是否重写,重写调用子类方法。其他情况均看父类类型
                    一句话总结:方法运行看右边,其他看左边
    */
    class Demo5
    {
        public static void main(String[] args) 
        {
            Animal animal = new Animal();      //动物是一种动物
            Animal animal2 = new Cat();           //猫是一种动物,多态:猫的实例对象,父类动物的引用
    
            //Cat cat2 = new Animal();           //动物是猫,不可以
            Cat cat = new Cat();               //猫是猫
    
            Animal a = new Cat();
            //成员方法:
            a.eat();   //喵吃了
            System.out.println(a.name);  //巴马
            System.out.println(a.age);   //80
        }
    }
    
    class Animal
    {
        String name = "巴马";
        int age = 80;
        public void eat(){
            System.out.println("吃了");
        }    
    }
    
    class Cat extends Animal
    {    
        String name = "加菲";
        int age = 40;
        public void eat(){
            System.out.println("喵吃了");
        }    
    }
    View Code

                   多太内存图:

            

        (4)前提:

             A:有继承或者实现关系。

             B:有方法重写。  (重要)

    /**
     * 多态的前提条件之一:必须要有方法的覆盖(即重写)
     */
    public class Test {
        public static void main(String[] args) {
            Animal animal = new Dog();
            animal.eat();
            // animal.sleep();  //报错,找不到符号,接口中没有sleep()抽象方法
        }
    }
    
    //接口
    interface Animal {
        public abstract void eat();
    }
    
    class Dog implements Animal {
        //继承的方法的重写
        public void eat() {
            System.out.println("狗吃");
        }
        //自己的方法
        public void sleep() {
            System.out.println("夹着尾巴睡");
        }
    }
    View Code

             C:有父类引用指向子类对象, 或者接口的应用指向实现类的对象

        (3)好处和弊端:

             A:好处

                 扩展性和维护性(是由继承和实现保证)。

    /*
        有两个类猪,狗继承动物,均有吃的动作。
        创建多个猪与狗,调用他们吃的功能。
        再来一个猫,创建多个猫的对象,调用猫的吃的功能
    */
    class Demo8_4
    {
        public static void main(String[] args) 
        {
            
            Pig pig = new Pig();
            Pig pig2 = new Pig();
            Pig pig3 = new Pig();
    
            Dog dog = new Dog();
            Dog dog2 = new Dog();
            Dog dog3 = new Dog();
            /*
            Animal pig = new Pig();
            Animal pig2 = new Pig();
            Animal pig3 = new Pig();
    
            Animal dog = new Dog();
            Animal dog2 = new Dog();
            Animal dog3 = new Dog();
            */
            //不需要调用不同的方法,只需要调用同一个animalEat的方法即可
            /*
            MyAnimalTool.pigEat(pig);
            MyAnimalTool.pigEat(pig2);
            MyAnimalTool.pigEat(pig3);
    
            MyAnimalTool.dogEat(dog);
            MyAnimalTool.dogEat(dog2);
            MyAnimalTool.dogEat(dog3);
            */
    
            MyAnimalTool.animalEat(pig);
            MyAnimalTool.animalEat(pig2);
            MyAnimalTool.animalEat(pig3);
            MyAnimalTool.animalEat(dog);
            MyAnimalTool.animalEat(dog2);
            MyAnimalTool.animalEat(dog3);
    
            
            Cat cat = new Cat();
            Cat cat2 = new Cat();
            Cat cat3 = new Cat();
            /*
            Animal cat = new Cat(); 
            Animal cat2 = new Cat(); 
            Animal cat3 = new Cat(); 
            */
            /*
            MyAnimalTool.catEat(cat);
            MyAnimalTool.catEat(cat2);
            MyAnimalTool.catEat(cat3);
            */
            MyAnimalTool.animalEat(cat);
            MyAnimalTool.animalEat(cat2);
            MyAnimalTool.animalEat(cat3);
        }
        /*
        public static void pigEat(Pig p) {
            p.eat();
        }
    
        public static void dogEat(Dog d) {
            d.eat();
        }
    
        public static void catEat(Cat c) {
            c.eat();
        }
        */
    }
    //定义动物类作为父类
    class Animal
    {
        public void eat(){
            System.out.println("吃");
        }
    }
    //定义猪与狗作为子类
    class Pig extends Animal
    {
        public void eat(){
            System.out.println("拱着吃");
        }
    }
    
    class Dog extends Animal
    {
        public void eat(){
            System.out.println("摇着尾巴吃");
        }
    }
    
    class MyAnimalTool
    {
        //多个动物均是Animal的子类,所以只需要定义一个方法接受Animal类型即可。从而加入新的动物时,该类代码不需要改动!
        /*
        public static void pigEat(Pig p) {
            p.eat();
        }
    
        public static void dogEat(Dog d) {
            d.eat();
        }
    
        public static void catEat(Cat c) {
            c.eat();
        }
        */
    
        public static void animalEat(Animal a) {
            a.eat();
        }
    }
    //添加猫类
    class Cat extends Animal
    {
        public void eat(){
            System.out.println("舔着吃");
        }
    }
    View Code

              B:弊端

                   不能使用子类的特有功能。

    /**
     * 多态的前提条件之一:必须要有方法的覆盖(即重写)
     */
    public class Test {
        public static void main(String[] args) {
            Animal animal = new Dog();
            animal.eat();
            // animal.sleep();  //报错,找不到符号,接口中没有sleep()抽象方法
        }
    }
    
    //接口
    interface Animal {
        public abstract void eat();
    }
    
    class Dog implements Animal {
        //继承的方法的重写
        public void eat() {
            System.out.println("狗吃");
        }
        //自己的方法
        public void sleep() {
            System.out.println("夹着尾巴睡");
        }
    }
    View Code

        (4)向上转型和向下转型

             A:向上转型

                 把子类对象赋值给父类或者接口引用 ,例子:

    /*
        向上转型:
            引用变量为父类时,子类实例对象可以自动提升为父类类型。即引用为父类型,可以赋值子类实例对象。
    */
    class Demo6 
    {
        public static void main(String[] args) 
        {
            Animal a = new Cat();   //多态本身的赋值就是向上转型。
            Cat c = new Cat();
    
            //method(c);
            //method(new Animal());  不可以
            //method(a);   不可以
    
            method2(a);
            method2(c);  //向上转型
    
            Cat c2 = method3();
            Animal a2 = method3();  //向上转型
    
            //Cat c3 = method4();
            Animal a3 = method4(); 
        }
    
        public static void method(Cat c) {
            System.out.println(c);
        }
    
        public static void method2(Animal animal) {
            System.out.println(animal);
        }
    
        public static Cat method3(){
            //return new Animal();
            return new Cat();
        }
    
        public static Animal method4(){
            //return new Animal();
            return new Cat();  //向上转型
        }
    }
    class Animal
    {
        String name = "巴马";
        int age = 80;
        
        public void eat(){
            System.out.println("吃了");
        }
        
    }
    
    class Cat extends Animal
    {    
        String name = "加菲";
        int age = 40;
    
        public void eat(){
            System.out.println("喵吃了");
        }
        
    }
    View Code

             B:向下转型

                   把父类或者父接口引用强制转换为子类,例子:

    /*
        向下转型:
            将父类强转成子类,前期父类引用指向的对象为子类对象,即必须是多态的引用。
    */
    class Demo7
    {
        public static void main(String[] args) 
        {
            Animal a = new Cat();
            Animal a2 = new Animal();
    
            Cat c = (Cat)a;
            //Cat c2 = (Cat)a2;   不可以
        }
    }
    
    class Animal
    {
        String name = "巴马";
        int age = 80;
        
        public void eat(){
            System.out.println("吃了");
        }
        
    }
    
    class Cat extends Animal
    {    
        String name = "加菲";
        int age = 40;
    
        public void eat(){
            System.out.println("喵吃了");
        }
        
    }
    View Code

        (5)多态中的使用成员特点

             A:成员变量

                   编译运行都看左边

             B:成员方法

                   编译看左边,运行看右边。

            总结: 全部看父类类型,只是在调用该方法时,检查子类是否重写,如果重写,调用之类方法,如果没有重写,调用父类的方法。

          (6)多态的体现形式

             A:具体类多态(几乎不用)

             B:抽象类多态

             C:接口多态

    2:抽象类(掌握)

          (1)多个具体的事物具备相同的方法声明,而方法体不同,我们就只抽取方法声明,然后定义到一个类中。

               而一个没有方法体的方法是一个抽象方法,一个类中有抽象方法,该类必须定义为抽象类。

          (2)抽象类的特点:

               A:抽象类或者抽象方法用abstract修饰。

               B:抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类。

               C:抽象类不能被实例化。

               D:子类继承抽象类,要么是抽象类,要么重写所有父类抽象方法。

            例子:

    /*
        抽象类:包含抽象方法的类
    */
    class Demo9 
    {
        public static void main(String[] args) 
        {
            //Animal a = new Animal();
            Animal a2 = new Pig();
            System.out.println("Hello World!");
        }
    }
    //定义动物类作为抽象父类
    abstract class Animal
    {
        public abstract void eat();
        public abstract void sleep();
        //public void sleep(){
        //    System.out.println();
        //}
    }
    //定义猪与狗作为子类
    class Pig extends Animal
    {
        public void eat(){
            System.out.println("拱着吃");
        }
    
        public void sleep(){
            System.out.println("躺着睡");
        }
    }
    /*
    abstract class Dog extends Animal
    {
        public void eat(){
            System.out.println("摇着尾巴吃");
        }
    }
    */
    class Dog extends Animal
    {
        public void eat(){
            System.out.println("摇着尾巴吃");
        }
        public void sleep(){
            System.out.println("压着尾巴睡");
        }
    }
    View Code

        (3)抽象类的几个小问题

             A:不能被实例化,要构造方法干啥?

                  给抽象类的成员变量赋值

             B:一个类中没有抽象方法,居然定义抽象类,有什么意义?

                  强制不让该类创建对象

             C:abstract抽象关键字不能和哪些关键字共存

                   a:private  抽象类的方法需要被覆盖,如果private修饰的话,子类无法访问

                   b:final   抽象类需要继承,final修饰的无法继承

                   c:static   抽象类抽象方法无方法体,调用无意义

        (4)抽象类的成员:

             A:成员变量 有变量,也有常量

             B:构造方法 有构造方法,用于子类访问父类数据的初始化

             C:成员方法 有抽象方法,也有非抽象的方法

        (5)抽象类的案例

           A:老师案例

           例子:

    /*
        老师示例
            具体事物:基础班老师,就业班老师
            共性:姓名,年龄,讲课。
    */
    class Test 
    {
        public static void main(String[] args) 
        {
            BaseTeacher bt = new BaseTeacher("刘正风",28);
            bt.setName("曲阳");
            bt.teach();
            System.out.println(bt.getName());
            bt.teach();
    
            WorkTeacher wt = new WorkTeacher("唐嫣",28);
            wt.teach();
    
            Teacher t = new BaseTeacher("刘正风",28);
            t.setName("曲阳");
            t.teach();
            System.out.println(t.getName());
    
            Teacher t2 = new WorkTeacher("唐嫣",28);
            t2.teach();
        }
    }
    //设计抽象概念老师类
    abstract class Teacher
    {
        private String name;
        private int age;
    
        public Teacher(){}
        public Teacher(String name,int age){
            this.name = name;
            this.age = age;
        }
    
        public abstract void teach();
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public int getAge() {
            return age;
        }
    }
    
    //定义基础班老师
    class BaseTeacher extends Teacher
    {
        public BaseTeacher(){}
        public BaseTeacher(String name,int age){
            super(name,age);
        }
    
        public void teach() {
            System.out.println("讲JavaSE");
        }
    }
    
    //定义就业班老师
    class WorkTeacher extends Teacher
    {
        public WorkTeacher(){}
        public WorkTeacher(String name,int age){
            super(name,age);
        }
    
        public void teach() {
            System.out.println("讲JavaEE/Android");
        }
    }
    View Code

    3:接口(掌握)

        (1)当一个抽象类中的方法都是抽象的时候,java就提供了一种更抽象的表达方式,叫接口。(接口里面的方法都是抽象的)

                a.定义接口:interface XX {}

                b.使用接口:class YY implements XX{}

              例子:

    /*
        比抽象类更为抽象的表现形式
        格式:
        定义接口:interface XX {}
        使用接口:class YY implements XX{}
        
    */
    class Demo11
    {
        public static void main(String[] args) 
        {
            //Cat cat = new Cat();
            Cat cat2 = new Student();
            Cat cat3 = new Person();
            System.out.println("Hello World!");
        }
    }
    
    interface Cat 
    {
        public abstract void climb();
    }
    
    interface Dog
    {
        public abstract void guanxianshi();
    }
    
    
    class Animal
    {
    }
    
    class Person extends Animal implements Cat,Dog
    {
        public void climb(){
            System.out.println("我爬了");
        }
    
        public void guanxianshi(){
            System.out.println("我就管了");
        }
    }
    
    class Student extends Animal implements Cat
    {
        public void climb(){
            System.out.println("我爬了");
        }
    
        public void guanxianshi(){
            System.out.println("我就管了");
        }
    }
    View Code

        (2)接口的成员特点:

             A:成员变量 是常量 默认修饰符 public static final

             B:成员方法 抽象方法 默认修饰符 public abstract

             c: 没有构造方法 (接口不能创建对象)

            例子:

    /*
        接口的成员有固定修饰符:
            变量:public static final 将变量变为常量,所以必须显示初始化
            方法:public abstract    一定为公共的抽象方法
    */
    class Demo12 
    {
        public static void main(String[] args) 
        {
            Computer c = new Person();
            c.play();
    
            System.out.println(Computer.NO1);
        }
    }
    
    interface Computer
    {
        //public static final String NO1 = "艾尼阿克";
        String NO1 = "艾尼阿克";
        //public abstract void play();
        //public void play();
        void play();
        //private void play(); 不能使用其他访问权限修饰符
    
    }
    
    class Person implements Computer
    {
        
        public void play(){
            System.out.println("敲个猜数字");
        }
        /*  不能使用默认的访问权限覆盖公共的访问权限
        void play(){
            System.out.println("敲个猜数字");
        }
        */
    }
    View Code

        (3)接口的特点:

             A:接口用interface定义

             B:实现类实现接口用implements标识

             C:接口不能被实例化

             D:子类实现接口的时候,要么是抽象类,要么全部实现接口方法

        (4)接口和类的关系

             A:类与类的关系

                   继承关系,只能单继承,可以多层继承。

             B:类与接口的关系

                   实现关系,可以单实现,也可以多实现。

                   还可以在继承一个类的同时,实现多个接口。 class A extends B implements C,D

             C:接口与接口的关系

                   继承关系,可以单继承,也可以多继承。

        (5)接口的思想特点(理解)

             A:对外暴露的规则(USB接口)

             B:程序的扩展功能(多态)

             C:降低程序的耦合性(多态)

             D:让类可以多实现

        (6)接口和抽象类的区别

             共性:都是不断抽取出来的抽象的内容。都不能创建实例对象。

             不同:

                  A:成员特点

                    抽象类:

                          成员变量 可以变量,也可以常量

                          成员方法 可以抽象,也可以非抽象

                          构造方法 有

                    接口:

                          成员变量 只能是常量, 固定修饰符public static final

                          成员方法 只能是抽象,固定修饰符public abstract

                          构造方法 无

                B:继承或者实现关系特点

                      a:类与类的关系(继承 extends)

                          继承关系,只能单继承,可以多层继承。

                      b:类与接口的关系(实现 implements)

                          实现关系,可以单实现,也可以多实现。

                          还可以在继承一个类的同时,实现多个接口。

                      c:接口与接口的关系(继承 extends)

                          继承关系,可以单继承,也可以多继承。

               C:设计区别

                    抽象类中定义的是体系的共性内容。表达的是:is a的关系。

                    接口中定义的是体系的扩展功能。表达的是:like a的关系。       

           简单总结:

                   均为抽取出的相同概念的抽象。都不能创建实例对象。

                    类为单继承,接口为多实现。

                    继承为”is a”的关系,接口为“like a”的关系。

                    抽象类中可以定义非抽象方法,共子类直接使用。接口均为抽象方法,因为固定修饰符。

        (7)如何实现一个继承体系

           分析:由具体到抽象

           实现:由抽象到具体

           

  • 相关阅读:
    android 权限大全
    Android限定EditText的输入类型为数字或者英文(包括大小写),EditText,TextView只能输入两位小数
    Android Application 对象介绍
    数据库关键字
    SQLite数据库增删改查操作
    【转】html之<meta> 标签
    javascript剔除数组重复元素的简单方法
    jQuery性能最佳实践
    css学习笔记
    【转】必须避免的html标签十宗罪
  • 原文地址:https://www.cnblogs.com/hezhiyao/p/7487736.html
Copyright © 2011-2022 走看看