• 面向对象4


    1、多态

    thinking in java3中的多态

    People are often confused by other, non-object-oriented features of Java, like method overloading, which are sometimes presented as object-oriented. Don't be fooled: If it isn't late binding, it isn't polymorphism

    按文面翻译

    人们总是被java的另一种非面向对象的特性所困惑,就像方法重载,有时候它以面向对象而存在,请不要犯傻,如果没有后期绑定(也就是运行期的动态绑定),它就不是多态.

    所以,这段话要表达的意思就是说,多态要有动态绑定,否则就不是多态,方法重载也不是多态(因为方法重载是编译期决定好的,没有后期也就是运行期的动态绑定)

    多态存在的三个必要条件

    • 继承
    • 重写
    • 父类引用指向子类对象

    比如:

    Parent p = new Child();

    多态的实现方式

    方式一:重写:

    方式二:接口

    • 1. 生活中的接口最具代表性的就是插座,例如一个三接头的插头都能接在三孔插座中,因为这个是每个国家都有各自规定的接口规则,有可能到国外就不行,那是因为国外自己定义的接口类型。

    • 2. java中的接口类似于生活中的接口,就是一些方法特征的集合,但没有方法的实现。具体可以看 java接口 这一章节的内容。

    方式三:抽象类和抽象方法

    多态的好处:提高代码的重用性,降低模块之间的耦合度

    package LESSON6;
    
    class Animal1{
        String name;
    }
    class Food1{
        String name;
    }
    class Feeder1{
        String name;
        public void  feed(Animal1 animal,Food1 food){
            System.out.println(name+"给"+animal.name+"喂"+food.name);        
        }
    }
    class Rabbit1 extends Animal1{}
    class Dog1 extends Animal1{}
    class Bone1 extends Food1{}
    class Carrot1 extends Food1{}
    
    public class DEMO8 {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            //多态的好处:提高代码的重用性,降低模块之间的耦合度
            Feeder1 feeder=new Feeder1();
            feeder.name="jack";
            
            Animal1 rabbit=new Rabbit1();
            rabbit.name="小白兔";
            Animal1 dog=new Dog1();
            dog.name="牧羊犬";
            Food1 bone=new Bone1();
            bone.name="大骨头";
            Food1 carrot=new Carrot1();
            carrot.name="胡萝卜";
            feeder.feed(rabbit, carrot);
            feeder.feed(dog, bone);
    
        }
    
    }
    package LESSON6;
    class Animal{
        public String name;
        public void eat(){
            System.out.println("动物具有吃的能力");
        }    
    }
    class Food{
        public String type;
    }
    class Feeder{
        public void feed(String name,String type){
            System.out.println("喂"+name+"吃"+type);        
        }    
    }
    class Dog extends Animal{
        //重写
        public void eat(){
            System.out.println("我喜欢吃骨头");
        }    
        //子类独有方法
        public void watchdoor(){
            System.out.println("看门");        
        }    
    }
    class Rabbit extends Animal{
        public void eat(){
            System.out.println("我喜欢吃胡萝卜");
        }
    }
    public class DEMO6 {
    
    //    多态:指对象的多种形态
    // 多态的前提:继承关系中
    // 多态的表现:向上转型和向下转型
    public static void main(String[] args) { //1 引用多态 Animal animal=new Animal();//父类的引用指向本类对象 Animal dog=new Dog();//父类引用指向子类对象(向上转型:子类对象->>父类对象) dog.name="狗";//通过父类的引用变量调用父类属性

    Dog dog1=(Dog)dog;//向下转型:父类对象->>子类对象(前提是先进行向上转型)
    Dog dog2=(Dog)Animal;//java.lang.ClassCastException类型转化异常(未进行向上转型)

    //2 方法多态 animal.eat();//创建本类对象时,调用的方法为本类方法。 //输出 动物具有吃的能力 dog.eat();//创建子类对象时,调用的方法为子类重写的方法或者继承的方法。 //输出 我喜欢吃骨头 //dog.watchdoor() //不能通过父类的引用调用子类独有的方法 Food food=new Food(); food.type="骨头"; Feeder Feed=new Feeder(); Feed.feed(dog.name,food.type); } }

    2、抽象类,抽象方法

    在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。

    抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。

    由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类。

    父类包含了子类集合的常见的方法,但是由于父类本身是抽象的,所以不能使用这些方法。

    在Java中抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口。

    package LESSON7;
    
    //抽象类:[修饰符] abstract class 类名
     abstract class Shape{
         //抽象方法:[修饰符] abstract 返回值类型 方法名 ([参数列表]);
         public abstract void area();
        
         //如果一个类中声明了抽象方法,该类必须是抽象类
         //抽象类中可以声明普通方法和抽象方法
         
         public void test(){
             System.out.println("test");
         }
          
      }
     class Circle extends Shape{
         public double r;
         public final double PI=3.14;
         
         public Circle(double r) {
            this.r=r;
        }
         @Override
        public void area() {
            System.out.println("该圆的面积是"+PI*r*r);
            
        }
     }
    
    public class demo {
        public static void main(String[] args) {
            Shape c=new Circle(2);
            c.area();
        }
    }

    3、接口

    接口多实现

    package LESSON7;
    interface A{
        public abstract void a();    
    }
    interface B{
        public abstract void b();    
    }
    interface C{
        public abstract void c();
    }
    //接口可以多实现,类只能单继承但可以多重继承
    class D implements A,B,C{
        @Override
        public void a() {
            System.out.println("a");
            
        }
        @Override
        public void b() {
            System.out.println("b");
            
        }
        public void c() {
            System.out.println("c");
            
        }
    }
    public class demo2 {
        public static void main(String[] args) {
            D d=new D();
            d.a();
            d.b();
            d.c();
            
            A d2=new D();
            d2.a();//只能调用a方法
    
        }
    
    }

    接口多继承

  • 相关阅读:
    L7-1 文本处理
    L6-14 继承多态
    L6-13 魔法方法
    L6-12 类的实例
    L6-11 综合运用
    L6-2 嵌套循环
    golang 关于引用类型
    golang close for channel
    go tip
    vscode官方文档
  • 原文地址:https://www.cnblogs.com/qfdy123/p/10952215.html
Copyright © 2020-2023  润新知