• Java面向对象三大特征


    封装
    继承
    继承中的方法覆盖
    多态

    封装

    • 封装的好处
      1、封装之后,复杂的事物被“包起来”了。复杂性封装,对外提供简单的操作入口。比如照相机,照相机内部结构、实现原理都很复杂,然而对于使用者就很简单。
      2、封装之后才会形成真正的“对象”,真正的“独立体”。
      3、封装意味着以后的程序可以重复使用,并且这个事物应该适应性比较强,在任何场合都适用。
      4、封装之后,对于事物本身,提高了安全性【安全级别高】。
    • 封装的步骤
      1、所有属性私有化,使用private关键字进行修饰,private表示私有的,修饰的所有数据只能在本类中访问。(例子:private int age,age属性私有化,在外部程序不能直接访问)
      2、对外提供简单的操作入口,也就是说以后外部程序要想访问age属性,必须通过这些简单的入口进行访问。(属性的访问形式:读取属性的值(get);修改属性的值(set)。)
      3、对外提供两个公开的方法,分别是set方法和get方法:想修改属性,调用set方法;想读取属性,调用get方法。
      4、set方法的命名规范:
      public void set+属性名首字母大写(形参){
      安全控制;
      Java代码;
      }
      例子:
    public void setAge(int a){
        if(a<0 || a>150){
          return;
        }
        age = a;
    }
    

    get方法的命名规范:
    public 参数类型 get+属性名首字母大写(){
    安全控制;
    Java代码;
    }
    例子:

    public int getAge(){
        if(a<0 || a>150){
          return;
        }
        return age;
    }
    

    5、setter和getter方法没有static关键字;有static关键字修饰的方法怎么调用:类名.方法名(实参);没有static关键字修饰的方法怎么调用:引用.方法名(实参)。

    继承

    • 作用
      基本作用:代码复用。
      重要作用是:有了继承才有以后“方法的覆盖”和“多态机制”。
    • 继承的语法格式:
      [修饰符列表] class 类名 extends 父类名{
      类体 = 属性 + 方法
      }
    • 单继承
      Java中只支持单继承,一个类不能同时继承很多类,只能继承一个类。在C++中支持多继承
      但是一个类也可以间接继承其他类,例如:
    C extends B{
    }
    B extends A{
    }
    A extends T{
    }
    

    C类直接继承B类,但是C类间接继承了A、T类

    • 关于继承中的一些术语
      B类继承A类:
      A类称为:父类、基类、超类、superclass
      B类称为:子类、派生类、subclass
    • 子类继承父类继承那些数据呢?
      私有的不支持继承
      构造方法不支持继承
      其他数据都可以被继承
    • 默认继承
      Java中假设一个类没有显示继承任何类,该类默认继承JavaSE库中提供的java.lang.Object类。
      //快捷键:查找类型[Open Type]:ctrl + shift + T;
      查找资源:[Open resource]:ctrl + shift + R
    继承中的方法覆盖
    • 方法覆盖
      1、方法覆盖又被称为方法重写(override)/(overwrite)
      2、什么时候使用方法重写?
      当父类中的方法已经无法满足当前子类的业务需求;
      子类有必要将父类中继承过来的方法进行重新编写;
    • 代码需要满足什么条件才能构成方法覆盖?
      1、方法重写发生在具有继承关系的父子类之间;
      2、方法重写的时候:方法名相同、返回值类型相同、形参列表相同;
      3、方法重写的时候:访问权限不能更低,可以更高;
      4、方法重写的时候:抛出异常不能更多,可以更少;
      5、建议方法重写的时候尽量复制粘贴!(因为容易出错,导致没有产生覆盖)
    • 重写标注
      1、为了避免错误,可以使用一个特殊的Java语法,称为重写标注,在子类的方法前面放一个@Override。
      2、该标注表示被标注的方法必须重写父类的一个方法。如果具有该标注的方法没有重写父类的方法,编译器将报告一个错误。例如,如果toString被错误地输入为tostring,将报一个编译错误。如果没有使用重写标注,编译器不会报告错误。使用标注可以避免错误。
    • 代码例子:
      在这里插入图片描述
      在这里插入图片描述
      访问权限不能更低:
      在这里插入图片描述
    • 注意
      私有方法不能继承,所以不能覆盖;
      构造方法不能继承,所以不能覆盖;
      静态方法不存在覆盖。
      覆盖只针对方法,不谈属性。

    多态

    • 关于Java中的多态语法机制
      1、Animal、Cat、Bird三个类之间的关系:
      Cat继承Animal
      Bird继承Animal
      Cat和Bird之间没有任何继承关系
    • 关于多态涉及到的几个概念:
      1、向上转型(upcasting):
      子类型 转换为 父类型
      又被称为自动类型转换
      2、向下转型(downcasting):
      父类型 转换为 子类型
      又被称为强制类型转换【需要加强制类型转换符】
      3、注意:向上转型和向下转型的前提是具有继承关系!(没有继承关系,程序是无法编译通过的)
      4、代码、例子及内存图
    //动物类
    public class Animal {
        public void move(){
            System.out.println("动物在移动");
        }
    }
    
    //猫类
    public class Cat extends Animal{
        //重写父类
        public void move(){
            System.out.println("猫在悄无声息地跑");
        }
    
        //子类对象特有
        public void catchMouse(){
            System.out.println("猫抓老鼠");
        }
    }
    
    //鸟儿类
    public class Bird extends Animal{
        //重写父类
        public void move(){
            System.out.println("鸟儿在飞翔");
        }
        
        //子类特有
        public void fly(){
            System.out.println("bird is flying!");
        }
    }
    
            //使用多态语法机制
            Animal a2 = new Cat();
            /*1、Java程序分为编译阶段和运行阶段*/
            /*2、先分析编译阶段,在分析运行阶段;
            编译无法通过,根本是无法运行的。*/
            /*3、编译阶段编译器检查a2这个引用的
            数据类型为Animal,由于Animal.class字
            节码当中有move()方法,所以编译通过了。
            这个过程我们成为静态绑定,编译阶段绑定。
            只有静态绑定成功之后才有后续的运行。*/
            /*4、在程序运行阶段, JVM堆内存当中
            真实创建的对象是cat对象,那么以下程
            序在运行阶段定会调用cat对象的move()方法,
            此时发生了程序的动态绑定,运行阶段绑定。*/
            /*5、调用的一定是Cat()方法,与重写不
            重写无关,无论是Cat类有没有重写move方
            法,运行阶段一定调用的是Cat对象的move
            方法,因为底层真实对象就是cat对象。*/
            a2.move();
            /*6、cat对象里除了move()方法还有
            catchMouse()方法,但是不能使用
            catchMouse()方法,因为程序编译的
            时候a2引用的数据类型Animal里面没有
            catchMouse()方法,所以编译不通过。*/
            /*7、父类型引用指向子类型对象这种机制
            导致程序存在编译阶段绑定和运行阶段绑定
            两种不同的形态/状态,这种机制可以称为一
            种多态语法机制。*/
    

    Animal和Cat之间存在继承关系,Animal是父类,Cat是子类。
    new Cat()创建的对象的类型是Cat,a2这个引用的数据类型是Animal,可见它们之间进行了类型转换。子类型转换成父类型,称为向上转型(upcasting)或者自动类型转换。
    Java中允许这种语法:父类型引用指向子类型对象。
    在这里插入图片描述

    • 怎么让以上的对象执行catchMouse()方法?
      1、a2是无法调用的,因为a2的数据类型是Animal,Animal中没有catchMouse()方法。
      所以要将a2强制类型转换为Cat类型。(属于子类转父类,所以其为强制类型转换)
      2、什么时候需要向下转型?
      当调用的方法是子类型中特有的,在父类中不存在的,必须进行向下转型。
      3、代码
            /*long x = 100L;
              int y = (int)x;*/
            Cat c2 = (Cat)a2;/*a2在上面的代码中
            被自动转换成了Animal类型,所以需要强转为Cat类型*/
            c2.catchMouse();
            //或者
            ((Cat) a2).catchMouse();
            
            
            //著名的异常:java.lang.classCastException
            Animal a3 = new Bird();
            /*1、以下程序编译是没有问题的,因为编译
            器检查到a3的数据类型是Animal,Animal和
            cat之间存在继承关系,并且Animal是父类型,
            cat是子类型,父类型转换成子类型叫做向下
            转型,语法合格。*/
            /*2、程序虽然编译通过了,但是程序在运行
            阶段会出现异常,因为JVM堆内存当中真实存在
            的对象是Bird类型, Bird对象无法转换成
            cat对象,因为两种类型之间不存在任何继承
            关系,此时出现了著名的异常:
            java.lang.classCastException.类型转换
            异常,这种异常总是在"向下转型的时候"会发生。*/
            Cat c3 = (Cat)a3;
    
    • “向下转型"存在隐患
      1、以上异常只有在强制类型转换的时候会发生,也就是说“向下转型"存在隐患(编译过了,但是运行错了!)
      2、向上转型只要编译通过,运行一定不会出问题: Animal a = new cat()
      3、向下转型编译通过,运行可能错误: Animal a3 = new Bird(); cat c3 = (Cat) a3;
      4、怎么避免向下转型出现的ClassCastException呢?
      使用instanceof运算符可以避免出现以上的异常。
    • instanceof运算符
      1、语法格式:(引用 instanceof 数据类型名)
      2、以上运算符的执行结果类型是布尔类型,结果可能是true/false
      3、关于运算结果true/false:
      假设: (a instanceof Animal)
      true表示:a这个引用指向的对象是一个Animal类型。
      false表示:a这个引用指向的对象不是一个Animal类型。
      4、代码
            Animal a3 = new Bird();
            if (a3 instanceof Cat){//a3是一个Cat类型的对象
                Cat c3 = (Cat) a3;
                c3.catchMouse();
            } else if(a3 instanceof Bird) {//a3是一个Bird类型的对象
                Bird b2 = (Bird) a3;
                b2.fly();
            }
    

    5、Java规范中要求:在进行强制类型之前采用instanceof运算符进行判断,避免ClassCastException异常的发生,这是一种编程的好习惯。

    • 低耦合,高扩展
      1、现有Master、Dog、Cat三个类:
      Master和Cat, Dog这两个类型的关联程度很强,耦合度很高,扩展力差。
      2、所以要降低程序的耦合度【解耦合】,提高程序的扩展力【软件开发的一个很重要的目标】
      3、创建一个Pet类,使Cat, Dog继承Pet
      这时Master主人类面向的是一个抽象的Pet,不再面向具体的宠物
      4、提倡:面向抽象编程,不要面向具体编程
      面向抽象编程的好处是,耦合度低,扩展力强。
    • 多态的作用是什么?
      降低程序的耦合度,提高程序的扩展力。
      能使用多态尽量使用多态。
      父类型引用指向子类型对象。
  • 相关阅读:
    typora 页内跳转
    shell脚本搭建redis集群
    Html
    python json模块
    jenkins 问题合集
    day05 每日一行
    day04 每次一行
    day03 每日一行
    day02
    day02 每日一行
  • 原文地址:https://www.cnblogs.com/yu011/p/12632615.html
Copyright © 2020-2023  润新知