java的三点特征(封装、继承、多态)

封装(属性私有、get/set)

  1. 封装的优点

    • 提高程序的安全性
    • 隐藏代码的实现细节
    • 统一接口
    • 系统可维护性增加
  2. 属性私有:指的是封装方法时定义属性时使用private;使用get、set方法去实现属性的传值。

    package com.oop;
    
    public class Student {
        //private关键字表示属性私有
        private String name;
        private int id;
        private char sex;
        //get 方法
        public String getName() {
            return name;
        }
        //set方法
        public void setName(String name){
            this.name=name;
        }
    }
    
    package com.oop;
    
    public class Application {
        public static void main(String[] args) {
            Student stu = new Student();
            stu.setName("英俊");//这里不能直接给对象赋值,要调用Student里的set方法
            System.out.println(stu.getName());//调用get方法获取到数据
        }
    }
    

继承

  1. 继承的本质是对一批类的抽象,从而实现对现实世界更好的建模。

  2. extends意思为扩展,子类是父类的扩展。

  3. Java类中只有单继承,没有多继承。(一个子类只有一个父类,一个父类可以有多个子类)

  4. 子类继承了父类后就会拥有父类的全部方法(public)。

  5. java中所有类都默认继承object类。

  6. super注意点:

    • super调用父类的构造方法,必须在构造方法的第一个。
    • super只能出现在子类的方法或者构造方法中。
    • super和this不能同时调用构造方法。
  7. super vs this:

    • 代表的对象不同:

      • this: 本身调用的这个对象
      • super: 代表父类对象的调用
    • 前提:

      • this:没有继承也可以使用
      • super:只能在继承条件下才可以使用
    • 构造方法:

      • this():本类的构造
      • super():父类的构造
  8. 父类与子类例子:

    package com.oop;
    
    public class Person {
        //一个类里什么都不写,他也有一个默认的方法(构造器)
        protected String name = "小魏";
        public void print(){
          System.out.println("Person");
      }
    }
    
    package com.oop;
    
    public class Student extends Person{
       private String name = "英俊";
       public void print(){
           System.out.println("Student");
       }
       public void text(String name){
           System.out.println(name);//Main中传进来的数据
           System.out.println(this.name);//类本身的数据
           System.out.println(super.name);//从person中继承而来的数据
       }
    }
    
    package com.oop;
    
    public class Application {
        public static void main(String[] args) {
            Student stu = new Student();
            stu.text("魏英俊");
        }
    }
    

    输出结果:

    魏英俊 //Student中(name)
    英俊 //Student中(this.name)
    小魏 //Student中(super.name)

  9. 方法的重写

    1.静态方法的重写:

    package com.oop;
    //父类B
    public class B {
        public static void text(){
            System.out.println("B=>text()");
        }
    }
    
    package com.oop;
    //子类A
    public class A extends B {
        public static void text() {
            System.out.println("A=>text()");
        }
    }
    
    package com.oop;
    
    public class Application {
        //静态方法与非静态方法区别很大
        public static void main(String[] args) {
            //方法调用只和左边定义的数据类型有关
            A a = new A();
            a.text();
            //父类的应用指向了子类
            B b = new A();
            b.text();
        }
    }
    

    输出结果:

    A=>text()
    B=>text()

  10. 非静态方法的重写:

    package com.oop;
    //父类B
    public class B {
        public  void text(){
            System.out.println("B=>text()");
        }
    }
    
    package com.oop;
    //子类A
    public class A extends B {
        @Override//方法的重写
        public void text() {
            super.text();
        }
    }
    
    package com.oop;
    
    public class Application {
        //静态方法与非静态方法区别很大
        public static void main(String[] args) {
            //方法调用只和左边定义的数据类型有关
            A a = new A();
            a.text();
            //父类的应用指向了子类
            B b = new A();
            b.text();
        }
    }
    

    运行结果:

    B=>text()
    B=>text()

  11. 非静态方法与静态的区别:

    package com.oop;
    //父类B
    public class B {
        public  void text(){
            System.out.println("B=>text()");
        }
    }
    
    package com.oop;
    //子类A
    public class A extends B {
    
        public void text() {
            System.out.println("A=>text()");
        }
    }
    
    package com.oop;
    
    public class Application {
        //静态方法与非静态方法区别很大
        public static void main(String[] args) {
            //方法调用只和左边定义的数据类型有关
            A a = new A();
            a.text();
            //父类的应用指向了子类
            B b = new A();
            b.text();
        }
    }
    

    运行结果:

    A=>text()
    A=>text()

可以对比1,3看出,当调用的是非静态方法,即没有加(static)时,子类才可以重写父类的方法,反之,子类不能。

重写的注意点:

  • 方法名必须相同

  • 需要有继承关系

  • 参数列表必须相同

  • 修饰符的范围可以扩大但不能缩小

  • 抛出的异常可以缩小但不能放大

  • 子类的方法和父类一直,但方法名不同

多态

  1. 注意事项:

    • 多态是方法的多态,属性没有多态
    • 父类和子类必须有联系,如果没关系会报错类型转换异常(ClassCastException)
    • 父类引用指向子类对象:Father f1= new Son();
  2. 多态的例子:

    package com.oop;
    //父类B
    public class B {
        public  void text(){
            System.out.println("father");
        }
    }
    
    package com.oop;
    //父类B
    public class B {
        public  void text(){
            System.out.println("father");
        }
    }
    
    package com.oop;
    
    public class Application {
        //静态方法与非静态方法区别很大
        public static void main(String[] args) {
            A a = new A();//
            B b = new A();//这里可以将b定义为B类型,这就是多态,
            B c =new A();
            a.text();
            b.text();//一但子类重写了父类的方法,就执行子类的方法。反之调用父类的方法
            ((A) c).say();//c.say()因为c是B类型,将c类型强制转换为A,才能调用A中的方法
        }
    }
    

类型转化

  1. 类型之间的转换(父 子)

  2. 父类引用指向子类的对象

  3. 把子类转换为父类:向上转型,直接(赋值)

  4. 把父类转换为子类,是为了父类能够调用子类的某些特有的方法,向下转型(强制转换)

  5. 方便方法的调用,减少重复代码

  6. 并且,当把一个父类型变量实例转换为子类型变量时,必须确保该父类变量是子类的一个实例,从继承链的角度来理解这些原因:子类一定是父类的一个实例,然而父类却不一定是子类的实例。在进行父类向子类的转换时,一个好的习惯是通过instanceof运算符来判断父类变量是否是该子类的一个实例,否则在运行时会抛出运行异常ClassCastException,表示类转换异常。

    Person person = new Student();
    System.out.println(person instanceof Student);//判断person是否是Student子类的一个实例,这里结果为True
    
posted @ 2021-07-23 17:29  荒废两年学JAVA  阅读(53)  评论(0)    收藏  举报