多态、抽象类、接口_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("喵吃了");
    }
}

多太内存图:

(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("夹着尾巴睡");
    }
}

   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("舔着吃");
    }
}

   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("夹着尾巴睡");
    }
}

(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("喵吃了");
    }

}

   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("喵吃了");
    }

}

(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("压着尾巴睡");
    }
}

(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");
    }
}

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("我就管了");
    }
}

(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("敲个猜数字");
    }
    */
}

(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)如何实现一个继承体系

分析:由具体到抽象

实现:由抽象到具体

时间: 2024-10-04 03:32:38

多态、抽象类、接口_DAY09的相关文章

java----基础(this,继承,多态,抽象类,接口)

this指针 this指针在类定义时用到,this属于用类实例化的对象,只能在定义类的时候使用:(在下面的代码中会有体现) 类变量&类方法 定义: 访问修饰符 static+数据类型+变量名 所有该类的对象均可访问,均可修改,不会在调用后初始化,相当于全局变量. 可以被所有对象访问到,并且可以通过类访问到  类名.类变量 静态方法 == 类方法 可以被类名和对象访问到 原则上类变量用类方法来访问 类方法中不能访问非类变量,类变量可以被非类方法访问. 四种访问控制符: public : 对外公开

JAVA基础笔记(很实用)继承-多态-抽象类-接口-异常-集合-IO-线程-Socket

第七章:Java继承 一.继承的概念 1.一个父类派生出一个子类的机制称为继承. 2.承是重用程序代码的有力手段,当多个类之间存在相同的属性和方法时,可以从这些类中抽象出父类. 3.们只需要在父类中定义这些属性和方法,而子类无须重新定义这些属性和方法,直接从父类继承即可. 4.通过继承,子类就会自动的拥有在父类中定义的属性和方法. 5.两个或多个类的成员中存在一部分相同的情况,通过继承机制,可以利用现有的类来创建新的类. 6.子类不但拥有父类的成员,还可以定义新的成员. 7.可以提高软件的可重用

06 面向对象:多态&抽象类&接口&权限修饰符&内部类

多态: /* 多态(polymorphic)概述 * 事物存在的多种形态 多态前提 * a:要有继承关系. * b:要有方法重写. * c:要有父类引用指向子类对象. * 成员变量 * 编译看左边(父类),运行看左边(父类). * 成员方法 * 编译看左边(父类),运行看右边(子类).动态绑定 * 静态方法 * 编译看左边(父类),运行看左边(父类). * (静态和类相关,算不上重写,所以,访问还是左边的) * 只有非静态的成员方法,编译看左边,运行看右边 */ class Demo_Polym

2019-05-17 Java学习日记之面向对象_多态&抽象类&接口

多态 多态的概述: A:多态(polymorphic) 事物存在的多种形态 B:多态前提 a:要有继承关系 b:要有方法重写c:要有父类引用指向子类对象 多态中的成员访问特点之成员变量: 成员变量:编译看左边(父类),运行看左边(父类)多态中的成员访问特点之成员方法:成员方法:编译看左边(父类),运行看右边(子类)多态中的成员访问特点之静态成员方法:静态方法:编译看左边(父类),运行看左边(父类)(静态和类相关,算不上重写,所以访问还是左边的)只有非静态的成员方法,编译看左边,运行看右边 多态的

JavaSE知识-09(面向对象_多态&抽象类&接口)

多态的概述及其代码体现 多态(polymorphic)概述 事物存在的多种形态 多态前提 a:要有继承关系. b:要有方法重写. c:要有父类引用指向子类对象. class Demo1_Polymorphic { public static void main(String[] args) { Cat c = new Cat(); c.eat(); Animal a = new Cat(); //猫是一只动物 //父类引用指向子类对象 a.eat(); } } class Animal { pu

黑马程序员--java基础之多态,抽象类,接口,匿名内部类

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 4.4 子类的实例化过程 子类中所有的构造函数默认都会访问父类中空参数的构造函数. 因为每一个构造函数的第一行都有一条默认的语句super();. 子类会具备父类中的数据,所以要先明确父类是如何对这些数据初始化的. 为什么子类实例化的时候要访问父类中的构造函数呢? 那是因为子类继承了父类,获取到了父类中内容(属性),所以在使用父类内容之前,要先看父类是如何对自己的内容进行初始化的. P.S.

PHP中多态,抽象类,接口,

小例子: 需求:公司定义一个接口让我们开发功能 usb.interface.php: 1 <?php 2 interface USB{ 3 4 public function run(); 5 } store.class.php: 1 <?php 2 include_once("./usb.interface.php"); 3 class store implements USB{ 4 5 public function run(){ 6 $this -> initi

初识JAVA(【面向对象】:pub/fri/pro/pri、封装/继承/多态、接口/抽象类、静态方法和抽象方法;泛型、垃圾回收机制、反射和RTTI)

JAVA特点: 语法简单,学习容易 功能强大,适合各种应用开发:J2SE/J2ME/J2EE 面向对象,易扩展,易维护 容错机制好,在内存不够时仍能不崩溃.不死机 强大的网络应用功能 跨平台:JVM,字节码 两个命令: javac helloworld.java:将Java文件编译为字节码的.class文件 java helloworld:运行Java程序...??暂时这么认为 数据类型: 普通数据类型:int a=3; 对象数据类型:使用关键字new,String s=new String("

19 抽象类 接口类 封装. 多态

主要内容: 1.  抽象类(接口类): 制定一个规范  : from abc import ABCMeta,abstractmethod class Payment(metaclass=ABCMeta): @abstractmethod def pay(self):pass class Alipay(Payment): def __init__(self,money): self.money = money def pay(self): print('使用支付宝支付了%s' % self.mon

java基础三 [深入多态,接口和多态](阅读Head First Java记录)

抽象类和抽象方法 1.抽象类的声明方法,在前面加上抽象类的关键词abstract abstract class canine extends animal{ public void roam(){} } 抽象类除了被继承过之外,是没有用途,没有值,没有目的.类中的方法可以当做子类的合约内容,合约是对其他程序的承诺协议 抽象类中可以带有抽象和非抽象的方法 如果类中有抽象方法,则类必定标识为抽象的. 2.抽象的方法没有实体 (因为方法中的程序代码没有意义.抽象类需要被extend过有意义,抽象方法一