面向对象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方法

    }

}

 

接口多继承

 

posted @ 2019-05-30 21:41  勤奋的园  阅读(146)  评论(0编辑  收藏  举报