• 面向对象汇总0503


    面向对象基本的基本理解

    一个具体的对象基本有两种特征:对象有什么和对象能做什么。
    对象有什么称为属性,对象能做什么称为方法。

    一切客观存在的事物都是对象,万物皆对象...

    提取某些对相同或者相似的属性和行为,归结出的抽象定义,称为:类
      1.类是相同或者相似的对象的一个模板,它描述一类对象的行为和状态

      2.类是具有相同属性和方法(行为)的对象的集合 

    Java是面向对象的语言,其一就体现在Java程序都是以类class为组织单元。

    定义一个class主要分为3步:

      1.定义类名

      2.编写类的属性(也可不定义)

      3.编写类的方法(也可不定义)

    一个类可以包含以下类型变量:

      1.局部变量:在方法,构造方法,语句块中定义的变量,用完销毁

      2.成员变量:定义在类中,方法体之外的变量。这种变量在创建对象时初始化

      3.类变量:也叫静态变量,类变量也声明在类中,方法体之外,但必须声明为 static 类型,静态变量随类的加载产生,与对象无关。

    类的创建语法: 类名 对象名 = new 类名();

    类可以看做是我们自己创建的数据类型,定义类时不会在内存中开辟空间,实例化时才会

    对象

    成员变量与局部变量

      成员变量:

        1.在类中,方法外定义,本类可用,也可被与本类相关的其他类使用

        2.作用域本类可见  

      局部变量:

        1.只能在所定义的方法中使用

      成员变量与局部变量同名共存时,局部变量有优先级

     

    象的创建过程

    1.new类名触发对象创建
    2.在内存中开辟对象空间
    3.为各个属性赋予初始值
    4.执行构造方法中的代码
    5.[将对象的地址赋值给变量]

    类对象内存分析图

    构造方法

    作用

        用于在开发过程中创建对象使用,创建对象目前的格式
        new 类名(有可能使用到的参数);
        
        类名(有可能使用到的参数); 这就是构造方法 Constructor
        
        构造方法可以初始化当前创建对象中的成员变量数据!!!

    格式

    格式:
        public 类名(所需初始化参数列表) {
            初始化语句;
        }
    细节:
        1. 构造方法的名字必须是类名,并且其他方法的名字不能是类名
        2. 构造方法没有返回值类型声明
        3. 初始化参数列表和正常的方法列表操作使用一致
        4. 初始化语句,大多数是都是一些赋值语句

    要求

    格式:
        public 类名(所需初始化参数列表) {
            初始化语句;
        }
    
    注意:
        如果在代码中程序员自行完成了构造方法,Java编译器不再提供自动生成的无参数构造方法。
    
    【强制要求】
        以后代码中无论什么时候都要给用户提供一个无参数构造方法使用

    构造方法执行顺序

    总结

        构造方法功能是用于初始化创建对象的成员变量数据
        构造方法是一个方法,参数使用方式和方法一致
    
    2. 构造方法选择
        Java编译器会根据构造方法中的【参数类型,个数,顺序】来做选择,如果没有指定的构造方法,报错!!!
    
    3. 无论什么时候一定要给当前类提供一个无参数构造方法。
    
    4. 【以下代码报错】
        Dog(String name);
        Dog(String color);
    
        调用:
            String color = "red";
            Dog dog = new Dog(color);
        在Java代码中不允许出现相同数据类型,个数,顺序的构造方法,和参数名没有关系,Java编译器选择过程中,有且只针对数据类型,个数,顺序选择,参数名真的无所谓。

    无参构造

    有参构造//构建有参构造方法时,要求提供参数,但是不使用参数会怎样?==>没有任何影响

    只有未提供构造方法时,系统才会默认提供无参构造方法;只要提供了,系统就不会再提供无参构造方法

    static

    static可以修饰属性,方法,代码块

    静态成员

      static修饰的成员为静态成员或者类成员,属于整个类所有,而不是某个对象所有,即被类的所有对象所共享。静态成员可以使用类名直接访问,也可以使用对象名进行访问(推荐使用类名访问,静态成员与对象的产生和消失没有关系,使用对象名访问时虚拟机会自动转为类名访问)

    实例属性:每个对象单独分别持有,单方面修改不会影响其他对象

    静态属性(类属性):类只有一份,所有对象共有,任何对象修改均会影响其属性

    static属性在方法区存在

    public class StaticTest{
        public static String string="shiyanlou";
        public static void main(String[] args){
            //静态成员不需要实例化 直接就可以访问
            System.out.println(StaticTest.string);
            //如果不加static关键字 需要这样访问
            StaticTest staticTest=new StaticTest();
            System.out.println(staticTest.string);
            //如果加上static关键字,上面的两种方法都可以使用
        }
    }

    static使用要点:

    static使用要点:
    
      1.static修饰的方法是静态方法,静态方法不依赖于对象,无需创建对象就可以通过类名调用
    
      2.static修饰的成员是静态成员,静态成员不依赖于对象,无需创建对象就可以通过类名调用
    
      3.static方法不能访问非静态成员变量和非静态方法,但是非静态成员变量和非静态方法可以访问静态方法
    
      4.由于不被实例化也可以调用,所有不能有this,super
    
      5.静态方法可以继承,不能重写,没有多态(使用@Override注解也会报错)
    
      6.静态代码块在类加载时被执行,且只执行一次

      7.上述要点的部分原因是:I:时间上:static在类被加载时就会执行,static语句执行时可能对象还未创建 II:空间上:一个类会创建多个对象,静态方法访非静态属性时,不能确认是访问的哪一个对象。((mc.b)会自动转换成(类名.b))

    //Arrays.copyOf();Array.sort();Math.random();

    第7点图例

    Java程序调用种类:

      java程序调用有两种调用方式:

      静态分派:静态分派中,允许参数列表不同的重名方法,指静态方法之间的重载

      动态分派:在具有继承关系的情况下,调用实例方法时,自低向上的查找可用的方法版本,指方法的覆盖

    方法调用的五个指令:jvm

      1.innokespecial 私有方法,构造方法

      2.invokeinterface 接口防范

      3.invokestatic 静态防范

      4.involkevirtual 虚方法(被子类覆盖的方法,抽象类)

      5.invokedynamic 动态链接方法

    【其他知识】

      方法在本类中可以通过“方法名()”直接访问,在其他类中通过“类名.方法名()”访问

    【问题】

     final关键字

    final可以修饰内容

      1.修饰类:该类不允许继承,为最终类

      2.修饰成员方法:则该方法不允许被覆盖(重写)

      3.修饰局部变量:则该变量只能赋一次值,即常量;赋值时机:显示初始化

      4.修饰成员变量:则该类的属性不会进行隐形初始化(类的初始化属性必须有值),在构造方法结束前赋值:显示初始化,动态代码块,构造方法中

      6.修饰静态变量:加载完成前赋值:显示初始化,静态代码块

      7.修饰基本数据类型:值不可变

      8.修饰引用数据类型:地址不可变

     代码实现

    /*
    final关键字可以修饰
        局部变量  有且只能被赋值一次,赋值之后不可以修改
        成员变量  定义时必须初始化,未初始化报错
        成员方法  使用final修饰的方法为最终方法,不能被重写!!!
        类 没有子类,不能被继承
            Java中是存在一些类是使用final修饰的
                String类
     */
    final class Father {
        final public void game() {
            System.out.println("黄金矿工!!!");
        }
    }
    
    // The type Son cannot subclass the final class Father
    // Son类不能是final修饰的类Father类的子类,不能继承Father
    // class Son extends Father {
        // The blank final field age may not have been initialized
        // 使用final修饰的成员变量还没有被初始化
        // final int age = 10;
        
        // Cannot override the final method from Father
        // 使用final修饰的方法为最终方法,不能被重写!!!
    //    public void game() {
    //        System.out.println("PUBG");
    //    }
    // }
    
    public class Demo1 {
        public static void main(String[] args) {
            
            final int num;
            num = 10;
            
            // The final local variable num may already have been assigned
            // 使用final修饰的局部变量num已经被赋值
            // num = 20;
        }
    }

    final修饰类

    class Dog {
        String name;
        int age;
    }
    
    public class Demo2 {
        public static void main(String[] args) {
            Dog dog = new Dog();
            
            dog.name = "八公";
            dog.age = 15;
            
            /*
             * final修饰的是dog1,dog1是一个类对象,同时是一个引用数据类型的变量。
             * dog1存储数据不可以改变!!!dog1指向不可以改变,但是dog1指向空间
             * 中的内容可以改变。
             * 
    
             */
            final Dog dog1 = new Dog();
            
            // dog1能不能操作成员变量???
            dog1.name = "骚杰";
            dog1.age = 16;
            
            // 能不能修改???
            dog1.name = "一杯二锅头";
            dog1.age = 20;
            
            Dog dog2 = dog1;
            dog2 = new Dog();
            
            // The final local variable dog1 cannot be assigned. 
            // It must be blank and not using a compound assignment
            // dog1 = new Dog();
        }
    }

    类加载

    JVM首次使用到某个类时,第二次用到不会加载。

    java_home:系统需要的class文件

    classpath:自己编写的class文件

    加载时机:

      1.创建父类对象

      2.创建子类对象

      3.访问静态属性

      4.调用静态方法

      5.Class.forName()主动加载一个类

    静态代码块

    动态代码块是写在类下面的"{}"的内容,动态代码块的执行地位由于构造方法

    执行顺序:动态代码块作用小体现在没有特殊的执行顺序

      创建对象==>执行构造方法(无父类)==>初始化属性==>动态代码块==>构造方法中代码

    静态代码块是写在类下面,在动态代码块之前:static,静态内容是在类加载时触发,只执行一次。

    静态属性,静态代码块这两项没有 执行先后顺序,谁在前谁先执行,一般将静态属性放在静态代码块之前。

    继承关系下的执行顺序

    创建对象==>父类静态属性==>父类静态代码块==>子类静态属性==>子类静态代码块==>父类实例属性==>父类实例代码块==>父类构造方法==>子类实例属性==>子类实例代码块==>子类构造方法

    封装

    封装:即隐藏对象的属性和实现细节,仅公开对外接口,控制在程序中属性的访问权限(包括读取和修改)

    封装概述 

    封装:
    归纳总结
    提高重用度
    降低使用难度,使用更方便
    
        循环封装过程
        方法封装功能
        类封装数据
        框架封装模块
    
        一段代码使用了三遍,做成一个循环
        一个循环使用了三遍,做成一个方法
        一个方法使用了三遍,做成一个工具类
        一个工具类使用了三遍,做成一个文档
        一个文档使用了三遍,做成一篇博客

    封装好处:

      1.只能通过规定方式访问数据

      2.隐藏类的实例细节,方便实现和修改

    如何封装:

      1.修改属性的可见性:设置修饰符为private
    
      2.创建setXXX和getXXX方法,控制属性
    
      3.在set和get方法中加入属性判断语句
    
      4.创建有参无参构造方法

    权限修饰符

    private
        私有化内容,使用private修饰的成员变量,成员方法和构造方法,有且只能类内使用,类外没有操作权限
        使用private修饰的内容有且只能在class所处大括号以内使用
    public
        公开内容,只要存在对应的类对象,都可以通过类对象调用类内的public修饰的成员变量和成员方法
    访问修饰符 本类 同包 子类 其他
    private OK      
    默认 OK OK    
    protected OK OK OK  
    public OK OK OK OK

    封装解决私有化变量的取值赋值问题

    private私有化修饰的成员变量,类外不能通过类对象操作,取值,赋值。
    
    JavaBean规范规定了
        setter ==> 赋值操作
        格式:
            public void set成员变量名(对应成员变量数据类型参数) {
                赋值操作;
            }
        getter ==> 取值操作
            public 对应成员变量数据类型返回值 get成员变量名字() {
                return 成员变量;
            }
    
    注意
        1. 方法格式固定,setter和getter方法操作过程不能修改
        2. 方法需要符合命名规范,小驼峰命名法
        3. boolean类型数据较特殊
            boolean类型的成员变量getter方法要求是is开头

    this

    this关键字在方法中可以区分成员变量和局部变量。

    this主要有三类结构:

      1. 当前类中的属性:this.属性

      2. 当前类中的方法(普通方法,构造方法):this(),this.方法名称()

      3. 当前对象:

    /*
     * this关键字在一个构造方法,调用其他构造方法
     * 注意事项:
     *         1. 不能通过this关键字调用当前所在构造方法,无穷递归!!!错误!!!
     *         2. this(实际参数); 根据实际参数的类型,个数和顺序来完成的
     *         3. Constructor call must be the first statement in a constructor
     *             通过this关键字调用其他构造方法,必须在当前方法体的第一行!!!
     *         4. 能不能在一个构造方法中,通过this关键字,同时调用两个构造方法???
     *             不能!!!因为构造方法调用必须在第一行,如果存在两个必然有一个在第二行,语法报错
     *         5. 两个构造方法,能不能通过this关键字相互调用???
     *             不允许,无穷递归!!!
     *         6. 规范化,统一化方法执行操作,提高代码的安全性和一致性!!!
     *      7. 构造方法相互调用时须留出程序出口
    * 8.this() 只能是调用的就是构造方法,使用时必须放在【构造方法】的【第一行】
    */

    //Dog()的递归都统一汇总到了三参构造的方法上面
    class Dog { private String name; private String color; private int age; public Dog() { this(null, null, 0); } public Dog(String name) { this(name, null, 0); } public Dog(String name, String color) { this(name, color, 0); } public Dog(String name, String color, int age) { this.name = name; this.color = color; this.age = age; } public void setName(String name) { this.name = name; } public String getName() { return name; } } public class Demo2 { }

    继承

    继承是类与类之间的衍生关系,父类更通用,子类更具体。

    继承代码格式:
    
    关键字:
      extends 
    格式:
      class A extends B {
    
    }
    1. A类使用extends关键字继承B类:
    2. A类是B类的一个子类,B类是A类的唯一父类
    3. 继承之后,子类可以通过继承得到父类中非私有化成员变量,和非私有化成员方法 4. 继承之后,子类不可以通过继承得到父类中的私有化成员变量,和私有化成员方法。
    5. 产生继承关系后,子类可以得到父类非私有属性和方法,同时也可以定义子类独有方法和属性     【Tips】:private修饰的内容有且只能在类内使用!!!

    继承实例

    // 定义父类
    //包含public和private的属性、方法各一个
    class Father {
        public int height;
    
        private int testPrivate;
    
        public void game() {
            System.out.println("钓鱼,象棋");
    
        }
    
        private void privateMethod() {
            System.out.println("私有化方法");
        }
    }
    /*
     * Son是Father的一个子类 
     * Father是Son的唯一父类
     */
    
    class Son extends Father {
        public int age;
    
        public void study() {
            System.out.println("子类好好学习,天天向上");
    
        }
    
    }
    
    
    //主类
    public class Demo {
        public static void main(String[] args) {
            // 创建一个Father类对象
            Father father = new Father();
    
            // 通过Father类的对象father,给内部成员变量赋值
            father.height = 170;
            father.game();
            System.out.println(father.height);
    
            System.out.println("---------");
    
            // 创建子类对象Son
            Son son = new Son();
    
            // son本身的属性和方法(成员变量,成员方法)
            son.age = 16;
            son.study();
    
            // son通过继承而来的方法属性
            son.height = 172;
            son.game();
    
            // 父类的私有化属性无法继承
            // - The field Father.testPrivate is not visible
            // son.testPrivate; 这是父类的私有属性
    
            // The method privateMethod() from the type Father is not visible
            // son.privateMethod(); 父类的私有化属性
    
        }
    }

     继承实例2(构造方法)

        子类对象创建过程中,在使用构造方法时,会默认调用父类的【无参数构造方法】。
        父类的构造方法,不是在创建父类的对象,只是在初始化父类的成员变量空间

    问题

    setget方法可以继承吗?==>可以继承

    子类可通过父类的setget方法获取父类的private变量?==>子类可通过getset方法隐式获得父类的private方法

    如何避免?

    /**
     * 测试类证明子类对象和父类对象中是同一个地址
     *
     */
    public class Test2 {
        public static void main(String[] args) {
            // 创建子类对象
            SonTest sonTest = new SonTest();
            // 通过setter设置父类的私有成员变量str
            sonTest.setStr("SubString");
            
            System.out.println(sonTest.getStr());
        }
    }
    
    /**
     * 示例父类
     *
     */
    class FatherTest {
      private String str;
    
    
      public FatherTest() {
        System.out.println("FatherTest():" + this);
      }
    
      public void setStr(String str) {
        this.str = str;
      }
    
      public String getStr() {
        return this.str;
      }
    }
    
    /**
     * 示例子类
     */
    class SonTest extends FatherTest {
    
      public SonTest() {
        System.out.println("SonTest():" + this);
      }
    
    }
    //测试结果
    
    FatherTest():com.qfedu.b.extendsDemo.SonTest@15db9742
    SonTest():com.qfedu.b.extendsDemo.SonTest@15db9742
    SubString

     继承可以解决代码重复冗余的问题:

      1.子类可以拥有父类除private以外的属性和方法

      2.子类可以拥有自己的属性和方法

      3.子类可以重写父类的方法

      4.Java中子类是单继承,一个子类只有一个父类

      【注意】Java实现多继承的一个办法是implements接口,但接口不能有非静态属性

    不可继承要点:

      1.构造方法只创建本类对象,不可继承;

      2.private修饰的属性和方法不可继承

      3.父子类不在同一个package包内,default修饰的属性和方法

     问题点:

      可访问就可继承吗?

    匿名对象

    匿名对象概述

    Person person = new Person("骚杰", 66, '男');
    
    Person 类名
    person 对象名
    new Person(...) 向内存的堆区申请空间,创建一个Person类对象使用的内存空间
    
    匿名对象
        没有名字的对象,没有对象名的对象
    格式:
        new 构造方法(所需参数)
    用途
        1. 提高开发效率,隐形眼镜日抛,一次性筷子
        匿名对象当前行使用之后,如果没有其他引用数据类型的变量保存其地址,直接销毁
        2. 简化代码结构
        3. 通过匿名对象直接调用成员方法
        4. 使用匿名对象作为方法的参数

    代码演示:

    package com.qfedu.a.computer2;
    
    public class Demo {
        public static void main(String[] args) {
            PC pc = new PC(new Screen("京东方",26.8F), new Keyboard("杂牌",84));//直接使用匿名对象将相关参数传入
        
            pc.show();
            System.out.println("--------------");
            
            
            // 换键盘
            pc.setKeyboard(new Keyboard("机械键盘",84));

         System.out.println(pc.getKeyboard().getName());// 通过“.”的方式可以得到匿名对象的值
    pc.show(); System.out.println(
    "--------------"); //换显示器 pc.setScreen(new Screen("杂牌", 28.8F)); pc.show(); System.out.println("--------------"); } }
    //
    Keyboard,Screen,PC 等其他类代码略
    
    

    匿名对象总结

    1. 匿名对象是为了提供开发效率,节约内存使用,同时让代码更加贴近于真实操作
    2. 匿名对象常用方式
        第一个是直接使用匿名对象调用成员方法
        第二个是直接使用匿名对象作为方法的参数
    3. 匿名对象【禁止】使用成员变量

    super0501

    super关键字作用

    1. super关键字可以用于在子类和父类之间,同名成员变量,同名成员方法调用时明确区分。
    2. super关键字可以显式调用父类的构造方法,用于初始化父类的成员变量数据。
    3. super关键字使用的格式,规范和this非常类似。
    4. 当子类和父类之间存在相同属性名称或者方法时,存在属性遮蔽,方法覆盖现象,可用super区分

    代码演示

    class Father {
        public String name;
        public String age;
        
        public void game() {
            System.out.println("黄金矿工");
        }
    }
    
    class Son extends Father {
        public String name;
        public String age;
        
        @Override
        public void game() {
            System.out.println("PUBG");
        }
        
        public void test() {
            // 调用子类的成员方法,就近元素
            game();
            
            // super关键字调用父类的game方法
            super.game();
            
            // 调用子类成员变量
            name = "大头儿子";
            
            // super关键字调用父类的成员变量
            super.name = "隔壁老王";
        }
    }
    
    public class Demo1 {    
        
    }

    继承关系下的对象创建过程

    在具有继承关系下的对象创建过程中,创建子类时会先创建父类对象。由父类的共性内容,加上子类的独有内容构成完整对象
    
    super()表示调用父类对象,隐式存在构造方法首行
    
    
    
    问题:
        super隐式存在首行和this显示存在时,执行谁?==>执行this
    
    写了this()时,super的隐式存在无效

     super,this访问子类,父类变量

    继承中的对象创建

     

      

    super关键字调用构造方法

    /*
     * super关键字在子类构造方法中,调用父类构造方法
     * 格式:
     *         super(实际参数);
     *         会根据实际参数来选择使用父类对应数据类型,个数,顺序的构造方法,用于初始化父类的
     *         成员变量数据。
     * 
     * 注意事项:
     *         1. 在没有指定选择哪一个父类构造构造方法,作为子类初始化父类成员变量空间的操作时
     *         Java编译器会默认选择父类的无参数构造方法。
     *         2. 选择使用父类的有参数构造方法,初始化父类成员变量空间
     *         3. 父类数据的交给父类的构造方法操作,不要在子类中操作。
     *         4. super关键字显式调用父类的构造方法,必须在代码的第一行
     *         5. super关键字调用构造方法,和this关键字调用构造方法,是否能共存???
     *             【显式】情况下不可以!!!
     *             但是省略通过super关键字调用父类构造方法的情况下,Java编译器会在
     *             编译的过程中,默认选择无参数父类构造方法使用
     */
    class Animal {
        private String name;
    
        public Animal() {
            System.out.println("Animal无参数构造方法");
        }
    
        public Animal(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    
    class Cat extends Animal {
        private String color;
    
        public Cat() {
            System.out.println("Cat无参数构造方法");
        }
    
        public Cat(String color) {
            this();
            this.color = color;
            System.out.println("Cat有参数构造方法");
        }
        
        public Cat(String color, String name) {
            super(name);
            this.color = color;
        }
    
        public String getColor() {
            return color;
        }
    
        public void setColor(String color) {
            this.color = color;
        }
    }
    
    public class Demo2 {
        public static void main(String[] args) {
            Cat cat = new Cat("玳瑁猫");
            
        }
    }

    方法重载【Overload】与重写【Override】0501

    方法重载:

      是指在【同一个类】中定义多个同名方法。【参数类型,数量,顺序不能一致,方法重载和修饰符,返回值无关】

      方法重载一般用于功能相似但是参数不同的方法里。(返回值,修饰符等可以不一样,但是尽量一样)

    重载能够解决的问题

    1. 简化代码结构,在同一个类内同名方法功能一致,但是参数满足多样化
    2. 简化程序员的开发压力
    3. 能够做到统一化处理方式
    //方法重载案例
    class
    Person { public void game() { System.out.println("大吉大利,今晚吃鸡"); } public void game(String name) { System.out.println("玩" + name); } public int game(String name, int time) { System.out.println("玩" + time + "个小时" + name); return 1; } } public class Demo1 { public static void main(String[] args) { Person person = new Person(); person.game(); person.game("LOL"); person.game("WOT", 2); } }

     方法重写:

    前提条件
        1. 重写是存在与继承中子类,或者【遵从中的实现类2. 重写情况下要求子类中的方法和父类中的方法,方法声明完全一致
        3. 方法体按照子类的情况来完成
        
    注意事项
        1. 子类重写父类方法,要求必须加上@Override严格格式检查
        2. @Override会检查子类重写的方法,方法声明是否和父类一致
    3. 子类覆盖父类方法后,调用子类方法时优先执行子类方法

    问题

      1.重写时如果方法与父类语法不一致会怎样?==>会生成子类的特有方法

    多态(dynamic binding)

    多态可分为:

      方法的多态:重写,重载

      对象的多态:对象向上转型,对象向下转型

    多态是不同类的对象对同一消息做出的响应,即同一消息可根据不同的发送对象而采用多种不同的行为方式。

    要理解多态必须要明白什么是"向上转型",比如,一段代码如下,Dog 类是 Animal 类的子类:

      Animal a = new Animal(); //a是父类的引用指向的是本类的对象

      Animal b = new Dog(); //b是父类的引用指向的是子类的对象

    在这里,可以认为由于 Dog 继承于 Animal,所以 Dog 可以自动向上转型为 Animal,所以 b 是可以指向 Dog 实例对象的。

    如果定义了指向子类的父类引用类型,那么它除了引用父类定义的属性和方法外,它还可以调用子类功能。但是对于只存在子类的方法和属性就不能获取。

    class Animal {
        //父类方法
        public void bark() {
            System.out.println("动物叫!");
        }
    }
    
    class Dog extends Animal {
    
        //子类重写父类的bark方法
        public void bark() {
            System.out.println("汪、汪、汪!");
        }
        //子类自己的方法
        public void dogType() {
            System.out.println("这是什么品种的狗?");
        }
    }
    
    
    public class Test {
    
        public static void main(String[] args) {
            Animal a = new Animal();
            Animal b = new Dog();
            Dog d = new Dog();
    
            a.bark();
            b.bark();
            //b.dogType();
            //b.dogType()编译不通过
            d.bark();
            d.dogType();
        }
    
    }

    在这里,由于 b 是父类的引用,指向子类的对象,因此不能获取子类的方法(dogType() 方法), 同时当调用 bark() 方法时,由于子类重写了父类的 bark() 方法,所以调用子类中的 bark() 方法。

    因此,向上转型,在运行时,会遗忘子类对象中与父类对象中不同的方法,也会覆盖与父类中相同的方法——重写(方法名,参数都相同)。

    向上转型

    概念:父类引用指向子类对象

    作用:屏蔽子类间差距;灵活,耦合性低

    多态中的方法覆盖:实际运行中,如果子类覆盖了父类的方法,则执行子类的方法。

    多态的应用场景:

    场景一:
      使用父类作为方法形参实现多态,使方法参数的类型更为宽泛
      调用方法时,可传递的实参类型包括:本类型对象+其所有的子类对象
    场景二:
      使用父类作为方法返回值实现多态,使方法可以返回子类对象
      调用方法后,可得到的结果类型包括:本类型对象+其所有的子类对象

    抽象类

    在定义类时,使用abstrac关键字修饰的类叫抽象类,abstract修饰的方法,子类必须重写

    抽象类不能new对象,但是可以声明引用

    抽象类中有抽象方法,这种方法时不要完整的,仅有声明而没有方法体。

    语法格式:

    abstract void f();  //f()方法是抽象方法

     语法特征

    1. abstract修饰的方法 没有方法体
    2. abstract修饰的方法,要求定义在abstract修饰的类内,或者接口interface内
    3. abstract修饰的类,你认为有没有类对象???
        abstract修饰的类内,是有可能存在abstract修饰的方法,而abstract修饰的方法是没有方法体的,如果能够得到一个abstract修饰类的对象,通过对象如何调用这些没有方法体的abstract方法。
    
    4. abstract修饰的类,然后呢类内没有任何的一个abstract修饰的方法,请问有意义吗?
        毫无意义!!!

    代码实现

    /**
     * LOL英雄类,每一个英雄都有QWER技能
     * 
     * @author Anonymous
     */
     /*
     * 第一步:
     *         使用abstract关键字修饰要求子类重写的方法
     * 【方法报错】
     *         Abstract methods do not specify a body
     *         abstract修饰的方法没有方法体
     * 【Eclipse快速修复】
     *         Ctrl + 1
     *         选择 Remove Method Body 删除方法体
     * 
     * 第二步:
     * 【方法报错】
     *         The abstract method q in type LOLHero can only be defined by an abstract class
     *         LOLHero类内的abstract修饰方法q(),有且只能定义在一个abstract修饰的类内
     * 【类名报错】
     *         The type LOLHero must be an abstract class to define abstract methods
     *         LOLHero类必须是一个abstract类,才可以定义abstract方法
     * 【语法要求】
     *         abstract修饰的方法,必须在定义在abstract修饰的类内或者XXXXXXXXXXXXXXXXXXXXXXXXX
     * 【Eclipse快速修复】
     *         Ctrl + 1
     *         选择 Make Type 'LOLHero' abstract 使用abstract修饰LOLHero类
     * 
     * 第三步:
     * 【子类报错】
     *         The type Thresh must implement the inherited abstract method LOLHero.q()
     *         Thresh类必须实现继承LOLHero类内的abstract方法q
     *         因为abstract修饰的方法,在父类abstract类内没有方法体,子类如果想要使用abstract修饰的方法
     *         必须完成方法体的实现
     * 【Eclipse快速修复】
     *         Ctrl + 1
     *         选择 Add unimplemented methods 添加未实现方法
     */
    abstract class LOLHero {
        abstract public void q();
    
        abstract public void w();
    
        abstract public void e();
    
        abstract public void r();
    }
    
    /**
     * 锤石类继承LOLHero类
     * 
     * @author Anonymous
     *
     */
    class Thresh extends LOLHero {
    
        @Override
        public void q() {
            System.out.println("死亡判决");
        }
    
        @Override
        public void w() {
            System.out.println("魂引之灯");
        }
    
        @Override
        public void e() {
            System.out.println("厄运钟摆");
        }
    
        @Override
        public void r() {
            System.out.println("幽冥监牢");
        }
    
    }
    
    /**
     * 维鲁斯类继承LOLHero类
     * 
     * @author Anonymous
     *
     */
    class Varus extends LOLHero {
    
        @Override
        public void q() {
            System.out.println("穿刺之箭");
        }
    
        @Override
        public void w() {
            System.out.println("枯萎箭袋");
        }
    
        @Override
        public void e() {
            System.out.println("恶灵箭雨");
        }
    
        @Override
        public void r() {
            System.out.println("腐败链锁");
        }
    
    }
    
    public class Demo1 {
        public static void main(String[] args) {
            Thresh saolei = new Thresh();
            saolei.q();
            saolei.e();
            saolei.w();
            saolei.r();
            
            System.out.println("--------------------------");
            
            Varus varus = new Varus();
            
            varus.q();
            varus.w();
            varus.e();
            varus.r();
        }
    }
    View Code

    接口

    2.接口
        接口语法:interface A {}
        
        接口内的成员变量【缺省属性】public static final
        接口内的成员方法【缺省属性】public abstract
        
        接口遵从的实现语法:
        class A implements B {}
        A类是B接口的实现类,A类遵从B接口
        接口的实现类需完成接口中所有缺省值为【public abstract】的方法
        
        一个类可以继承多个接口,接口可以继承接口
        
        abstract修饰的类遵从接口,相对于非abstract修饰的类有什么区别?==>abstract遵从接口不强制实现任何方法
        
        JDK1.8新特性:
            default关键字可以在接口中使用,用于修饰方法。使用default关键字修饰的方法在接口中允许有方法体。
            【默认方法】 【非强制重写方法】
            interface 接口内如果有default修饰的方法,那么这个接口的实现类可以不必强制重写default的方法
        
        
    3.多态
        一个方法需要的参数的是父类,那么传入父类以及父类的子类都是可以的
        一个方法返回的参数的是父类,那么返回父类以及父类的子类都是可以的
        
        一个方法需要的参数时USB接口,但是传入的对象是USB接口的实现类或者间接类也是OK的        
        
        【多态】
            父类引用指向子类的对象
            接口的引用指向遵从接口的类对象

    类与类之间的关系:单继承

    接口与接口之间关系:多实现

    接口与接口之间关系:多继承

    常量的定义方式:
        1.类方法初始化常量,将构造方法私有化,组织用户创建对象
        2.接口常量,将所有用到的常量汇总在接口中
    枚举类型:
        enum light{
    }

    内部类

    成员内部类

    静态内部类

    局部内部类

    匿名内部类

    package

    【附加】

    1.  javac -d xxxx.java 带包编译(文件夹)
    2.  import:找到对应的class文件,引入进来就能用
    3.  public 修饰的类要和文件名一致

    【更新履历】

    1.  增加继承,内部类
    2.  this,super

    【面向对象代码实现】

    1.面向对象案例 - 多类合作 - 汽车修理

    2.面向对象案例 - 多类合作 - 电脑组装

    3.面向对象案例 - 创建并操作数组

    4.面向对象案例 - 多类合作 - 汽车修理2

    5.面向对象案例 - 学生信息管理系统V0.6

    6.面向对象案例 - static修饰符执行顺序

  • 相关阅读:
    【大厂面试】字节跳动、京东等大厂面试题分享,已拿字节offer~
    听说这十道面试题,把百分之八十的程序员都淘汰了?不是吧,阿sir
    阿里大神的刷题笔记.pdf
    在家学了6个月,拿到阿里offer!
    【面试题】2020年底总结200道带答案的常见Java面试题!
    面试一家小公司,被问了 1 个小时并发编程。。全程已记录!
    分享一份技术书籍《Java 8 》PDF版,可自行下载
    Delphi的TDataSetProvider、TDataSet、TAdoQuery、TDataSource、TDataModule控件的组合使用
    初学Delphi与sql server的存储过程
    delphi简单的分页实现(高手可以不看)
  • 原文地址:https://www.cnblogs.com/raising/p/12764509.html
Copyright © 2020-2023  润新知