面向对象高级day02--知识总结

目录

 

一,多态

        1.多态概述

        2.多态中成员的访问特点

        3.多态的好处和弊端

        4.多态中的转型

        5.多态的内存图解

二,抽象类

        1.抽象类概述

        2.抽象类的特点

        3.抽象类的成员特点

三,接口

        1.接口类概述

        2.接口的特点

        3.接口垫成员特点

        4.类和接口的关系

        5.抽象类和接口的区别

        6.接口新增的方法

四,代码块(补充)

五,内部类

        1.内部类概述

        2.内部类分类

        3.成员内部类

        4.局部内部类

        5.匿名内部类

        6.内部类在开发中的应用


一,多态

        1.多态概述

               1).定义: 指的是同一个对象,在不同时刻表现出来的多种形态。

                2).多态含义:一种事物,多种形态。

                3).代码体现:父类引用指向子类对象,父类引用调用方法,执行的是子类重写的方法

//Animal是父类,变量的类型是Animal就代表父类引用。
//Dog是子类,我们new的是Dog的对象就代表指向的子类的对象。
Animal a = new Dog();

                4). 前提三要素:继承或实现子类重写方法向上转型(父类应用指向子类对象)

package com.itheima01;

/*
    TODO: 多态
        1. 含义: 一种事物,多种形态
        2. 代码体现:
                父类引用指向子类对象,父类引用调用方法,执行的是子类重写的方法
        3. 前提三要素
            1). 继承
            2). 重写
            3). 向上转型
 */
public class Demo {

    public static void main(String[] args) {
        //父类引用指向子类对象
//        Animal a = new Cat();
        Animal a = new Dog();
        //父类引用调用方法,执行的是子类重写的方法
        a.eat();
    }
}

        2.多态中成员的访问特点   

               a. 成员变量:编译看左边,执行看左边 (了解)

               b. java的生命周期
                    1). 三个阶段
                        源码(source)       ->      编译(compile)      ->  运行 (runtime)
                         java文件                    class字节码文件          Class对象(内存)
                                       javac编译指令                java运行命令
                    2). 编译器 : 编译
                            把java源码转成java字节码,在这个过程中会对源码的语法和逻辑进行一定的校验
                    3). JVM : 运行
                            运行java字节码 

                c. 成员方法:编译看左边,执行看右边 (重点)

                        1). 赋值是运行阶段的事情,运行看右边
                        2). 编译在运行之前,无法预知运行的结果,只能看左边 

                注:为什么成员变量和成员方法的访问不一样呢?

                        因为成员方法有重写,而成员变量没有

public class Animal {
    public int age = 40;
    public void eat() {
        System.out.println("动物吃东西");
    }
    public int getAge(){
        return age;
    }
}
public class Cat extends Animal {
	//跟父类同名的变量
    public int age = 20;
    //子类特有属性	
    public int weight = 10;
    //方法重写
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
     public int getAge(){
        return age;
    }
	//子类特有方法
    public void playGame() {
        System.out.println("猫捉迷藏");
    }
}
/*
    测试类
 */
public class AnimalDemo {
    public static void main(String[] args) {
        //有父类引用指向子类对象
        Animal a = new Cat();
		//访问的是父类的age变量
        System.out.println(a.age); //40
        //编译报错: 编译看左边,a是父类类型,只看父类中是否有weight变量,没有就报错
		//System.out.println(a.weight);
		
        //访问的是子类特有方法,是因为方法重写机制
        //父类的eat方法用于编译,子类的eat方法用于执行	
        a.eat();
        //编译报错: 编译看左边
//        a.playGame();
         System.out.println(a.getAge());//20

    }
}

        3.多态的好处和弊端

                a.好处:简化代码,提高了程序的扩展性。

                 具体体现:定义方法的时候,使用父类型作为参数,将来在使用的时候,使用具体的子                                     类型参与操作,当需求变化的时候,代码改的越少,扩展性越强。

                b.弊端 :不能使用子类的特有功能

                 注:应用场景

                        多态一般使用在方法的参数列表中.把方法的参数设置为父类类型,这样任意的子类                           对象都可以传进来,这样的好处是不管增加了多少子类,我们都不需要增加方法,提高                           代码的扩展性

        4.多态中的转型

                a.向上转型>从子到父:父类引用指向子类对象

                        Animal a = new Dog();

                b.向下装型(强转: 强制类型转换)>从父到子 :父类引用转为子类对象

                        语法:        子类类型 变量名 = (子类类型)父类类型的变量
                                        Dog g = (Dog)a;

                        向下转型有风险
                            1). 类型转换异常 ClassCastException
                                Cat类型的对象不能转换成Dog类型的变量
                            2). 规避风险: instanceof
                                如果a是Dog类型,result就是true,否则就是false
                                boolean result = a instanceof Dog;

package com.itheima03;

/*
    TODO 多态的弊端
        1. 弊端: 父类引用不能调用子类特有方法 (编译看左边)
        2. 向下转型(强转: 强制类型转换)
            1). 概念
                I. 向上转型: 父类引用指向子类对象
                    Animal a = new Dog();
                II. 向下转型: 子类引用指向父类类型引用
            2). 语法
                子类类型 变量名 = (子类类型)父类类型的变量
                Dog g = (Dog)a;
        3. 向下转型有风险
            1). 类型转换异常 ClassCastException
                Cat类型的对象不能转换成Dog类型的变量
            2). 规避风险: instanceof
                如果a是Dog类型,result就是true,否则就是false
                boolean result = a instanceof Dog;

 */
public class Demo02 {

    public static void main(String[] args) {

        Dog dog = new Dog();
        //喂狗,并且让狗看家
        keepPet2(dog);

        Cat cat = new Cat();
        //喂猫
        keepPet2(cat);

    }

    public static void keepPet2(Animal a){
        a.eat();
        //编译报错: 编译看左边, 父类引用不能调用子类特有方法
//        a.lookDoor();
//        boolean result = a instanceof Dog;
//        if(result){
        if(a instanceof Dog){
            Dog g = (Dog)a;
            g.lookDoor();
        }
    }

}

        5.多态的内存图解

 instanceof        它的作用是测试它左边的对象是否是它右边的类的实例, 返回 boolean 的数据类                                型,如果是 结果为true,如果不是 结果为false

格式:        if(对象 instanceof 类名/接口名){、、、 }

例如:

  public static void userAnimal(Animal a){//Animal a = new Dog();
        a.eat();
        //如果传入的是只狗  就调用它的lookHome()//实例
        if(a instanceof Dog){
            Dog d = (Dog)a;
                 d.lookHome();
        }

    }

二,抽象类

        1.抽象类概述

                 在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类                   必须定义为抽象类

//拥有抽象方法的类必须是抽象类
public abstract class Animal {
       /*
       public void eat() {
           System.out.println("吃东西");
       }
       */
    //抽象方法: 没有方法体的方法
    public abstract void eat();
}
class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }
}

public class Demo {

    public static void main(String[] args) {
        Animal a = new Dog();
        //父类方法只用于编译,子类方法才用于执行
        a.eat();
    }
}

为什么要使用抽象?>当一个类中有一个方法,这个方法必须要让子类去重写,就可以把这个方法定                                 义成抽象方法.(理解即可) 

        2.抽象类的特点           

                1).抽象类和抽象方法必须使用 abstract 关键字修饰

                        public abstract class 类名 {};

                        public abstract void eat();

                2).抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类

                3).抽象类不能实例化(不能被创建对象) 

                        抽象类如何实例化呢?参照多态的方式,通过子类对象实例化,这叫抽象类多态。

                4).抽象类的子类 

                        要么重写抽象类中的所有抽象方法,要么是抽象类。

                5).抽象类的主要作用: 所有的子类共性抽取 

                6).抽象类和普通类的区别:

                         普通类所拥有的,抽象类都有,而且还多了一个抽象方法

                         抽象类不能实例化

public abstract class A {

    public void method(){
        System.out.println("method");
    }

    public abstract void method02();
    public abstract void method03();
}
//子类要么是抽象类
abstract class B extends A{

}
//子类要么重写所有的抽象方法
class C extends A{
    @Override
    public void method02() {
        System.out.println("method02");
    }
    @Override
    public void method03() {
        System.out.println("method03");
    }
}
public class Demo {

    public static void main(String[] args) {
        //抽象类不能实例化
        //A a = new A();
    }
}

        3.抽象类的成员特点

                1).抽象类成员变量可以是变量也可以是常量。

                2).抽象类的构造方法

                       有构造方法,但是不能实例化

                        那么,构造方法的作用是什么呢?用于子类实例化时, 对父类数据进行初始化  

                3).抽象类的成员方法

                        可以有抽象方法:限定子类必须完成某些动作

                也可以有非抽象方法:提高代码复用性

public abstract class A {
    public int a;
    public static final int AGE = 1;

    public A() {
    }

    public A(int a) {
        this.a = a;
    }

    //下定义
    //所有A的子类对象必然有method01方法
    public abstract void method01();
}
public class Demo {

    public static void main(String[] args) {

        System.out.println(A.AGE);
    }
}

三,接口

        1.接口类概述

                扩展:# java的类型
                        a. 基本类型        byte  int  short  long  float  double  boolean  char
                        b. 引用类型
                                1). class : 类
                                2). interface : 接口
                                3). annotation : 注解
                                4). enum : 枚举 

                概述:接口就是一种公共的规范标准,Java中的接口更多的体现在对行为的抽象

                        我们可以使用接口来定义一些规则(比如要求某个方法的方法名必须叫什么,方法                         的参数列表必须是什么,方法的返回值类型必须是什么)

                定义格式: public interface 接口名{}

//接口: 规范,标准
public interface Usb {
    public abstract void chongDian();
}
//类实现接口: 继承
class Mouse implements Usb{
    @Override
    public void chongDian() {
        System.out.println("鼠标在充电");
    }
}

        2.接口的特点

                1).接口用关键字interface修饰        public interface 接口名 {} 

                2).类实现接口用implements表示        public class 类名 **implements** 接口名 {}

                3).接口不能实例化

                        接口如何实例化呢?参照多态的方式,通过实现类对象实例化,这叫接口多态

                        多态的形式:具体类多态,**抽象类多态,接口多态**

                        多态的前提:有继承或者实现关系;有方法重写;有父(类/接口)引用指向(子/实现)                                               类对象

                4). 接口的实现类        要么重写接口中的所有抽象方法,要么是抽象类 

        3.接口垫成员特点

                1).接口的成员变量特点:

                                                只能是常量        

                                                默认修饰符:**public static final** 

                 2).构造方法:        接口没有构造方法,因为接口主要是扩展功能的,而没有具体存在

                                              一个类如果没有父类,默认继承自Object类 

                 3). 接口的成员方法特点:

                                                只能是抽象方法

                                                默认修饰符:**public abstract**

/*
    TODO 接口的成员特点
    1.  成员变量
        1). 只能是常量
        2). 默认修饰符: public static final
    2. 成员方法
        1). 只能是抽象方法(JDK8之前)
        2). 默认修饰符: public abstract
    3. 构造方法
        没有!

    快捷键: ctrl + i(implements) 提示所有未重写的抽象方法
 */
public interface A {

    public static final int AGE = 1;
    int AGE2 = 2;

    public abstract void method01();
    void method02();
}
abstract class  B implements A{
    @Override
    public void method01() {

    }
}
class C implements A{
    @Override
    public void method01() {

    }

    @Override
    public void method02() {

    }
}

        4.类和接口的关系

                1).类和类的关系

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

                2).类和接口的关系

                        实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口

                3). 接口和接口的关系

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

/*
    1. 类和类的关系: 继承 extends
        Java的类只能单继承,不能多继承,可以多层继承
    2. 类和接口的关系: 实现 implements
        Java的接口支持多实现
    3. 接口和接口的关系: 继承 extends
         Java的接口支持多继承
 */
public class A {
}
//常见
class B extends A{
}
interface C{
}
interface D{
}
//常见
class E implements C,D{
}
//常见
class F extends B implements C,D{
}
interface G extends C,D{

}

        5.抽象类和接口的区别

        1). 成员区别

                抽象类 :  变量,常量;有构造方法;有抽象方法,也有非抽象方法

                接口 :  常量;抽象方法

        2). 关系区别

                类与类 :  继承,单继承

                类与接口 :  实现,可以单实现,也可以多实现

                接口与接口 :  继承,单继承,多继承

        3). 设计理念区别

                抽象类 :  对类抽象,包括属性、行为        满足 'is a' 的关系

                接口 :  对行为抽象,主要是行为        满足 'have a'的关系

        6.接口新增的方法

                1).接口中默认方法的定义格式: 

                格式:public default 返回值类型 方法名(参数列表) {   }

                范例:public default void show1() {   }

                接口中默认方法的注意事项

                        public可以省略,default不能省略

                2). 接口中静态方法的定义格式:

                        格式:public static 返回值类型 方法名(参数列表) {   }

                        范例:public static void show2() {   }

                        接口中静态方法的注意事项

                          静态方法只能通过接口名调用,不能通过实现类名或者对象名调用
                         public可以省略,static不能省略

        3).接口中私有方法的定义格式:

                格式1:private 返回值类型 方法名(参数列表) {   }

                范例1:private void show3() {   }

                范例1:private void show3() {   }

                格式2:private static 返回值类型 方法名(参数列表) {   }

                范例2:private static void show4() {   }

                接口中私有方法的注意事项

                        默认方法可以调用私有的静态方法和非静态方法
                        静态方法只能调用私有的静态方法
//预告: 主要为JDK8引入函数式编程做铺垫
public interface A {

    //JDK8: 默认方法
    public default void method01(int a){
        method05();
        System.out.println(a);
    }
    //public默认省略
    default void method02(){
        method05();
        System.out.println("method02");
    }

    //JDK8: 静态方法
    public static void method03(){
        System.out.println("method03");
    }
    // public默认省略
    static void method04(){
        System.out.println("method04");
    }

    //JDK9: 私有方法
    private void method05(){
        System.out.println("method05");
        System.out.println("method06");
        System.out.println("method07");
    }

}

四,代码块(补充)

        根据其位置和声明的不同,可以分为:

                局部代码块

                构造代码块

                静态代码块

                同步代码块(未来学)

package com.itheima13;

public class Student {
    static{
        System.out.println("静态代码块");
    }
    {
        System.out.println("构造代码块");
    }

    public Student(){
        System.out.println("构造方法");
    }

}
package com.itheima13;

/*
    TODO 代码块
        1. 局部代码块(了解)
            1). 写在方法内部的代码块
            2). 作用: 限定变量的使用范围
        2. 构造代码块(了解)
            1). 写在成员位置的代码块
            2). 特点: 创建对象时调用,优先于构造方法执行,每创建一个对象,就执行一次
        3. 静态代码块 (重要)
            1). 写在成员位置的静态代码块
            2). 特点: 随着类的加载而执行,只执行一次
            3). 作用: 适合资源初始化

 */
public class Demo {//类体 class body

    public static void main(String[] args) {//方法体 method body

        int a = 1;
        {//代码块 code block
            int b = 2;
        }

//        System.out.println(a);
//        System.out.println(b); //不能用

        Student s = new Student();
        Student s2 = new Student();


    }
}

五,内部类

        1.内部类概述

                1).内部类:就是在一个类中定义一个类。举例:在一个类A的内部定义一个类B,类B就                                    被称为内部类 

                2).内部类的定义格式:

public class 类名{
     修饰符 class 类名{
      } 	
}
//范例
public class 类名{
     修饰符 class 类名{
      } 	
}

                3).内部类的访问特点:

                内部类可以直接访问外部类的成员,包括私有
                外部类要访问内部类的成员,必须创建对象

        2.内部类分类

                按照内部类在类中定义的位置不同,可以分为如下两种形式

               a. 在类的成员位置:成员内部类

               b. 在类的局部位置:局部内部类

        3.成员内部类

                成员内部类,外界如何创建对象使用呢?

                格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象;

                范例:Outer.Inner oi = new Outer().new Inner();

        4.局部内部类           

               a.局部内部类是在方法中定义的类,所以外界是无法直接使用,需要在方法内部创建对象                并使用 

              b.该类可以直接访问外部类的成员,也可以访问方法内的局部变量

        5.匿名内部类

                前提:存在一个类或者接口,这里的类可以是具体类也可以是抽象类

                格式: 

new 类名或者接口名() {
	重写方法;
};
//范例
new Inter() {
	public void show() {
	}
}

        本质:是一个继承了该类的子类匿名对象,或者是一个实现了该接口的实现类匿名对象

        6.内部类在开发中的应用

                 需求:给按钮添加事件

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值