JAVA06 封装继承多态 总结(初级)

Posted 杰西啊杰西

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA06 封装继承多态 总结(初级)相关的知识,希望对你有一定的参考价值。

教程:B站韩顺平

目录

一、访问修饰符

二、封装

  1. 将属性进行私有化【不能直接修改属性】
  2. 提供一个公共的set方法,用于对属性判断并赋值
  3. 提供一个公共的fet方法,用于获取属性的值

tips:将有防护功能的方法写在构造器中,也可以实现防护属性

三、继承

3.1 继承

继承可以解决代码复用,当多个类存在相同属性(变量)和方法时,可以从种抽取父类,在父类中重新定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过extends继承即可

3.1.1 super关键字

  1. super表示父类的引用,用于访问父类的属性,方法,构造器

  2. 基本语法

    • 访问父类的属性,不能访问父类的private属性
      super.属性名
      
    • 访问父类的方法,不能访问父类的private方法
      super.方法名(参数列表);
      
  3. 访问父类的构造器:super(参数列表只能放在构造器的第一句,只能出现一句!)
    student.java

    public class student 
    		    private String name;
    		    private int age;
    		    public student()
    		    public student(String name, int age)
    		        setName(name);
    		        setAge(age);
    		    
    		
    		    public void setName(String name) 
    		        this.name = name;
    		    
    		
    		    public void setAge(int age) 
    		        this.age = age;
    		    
    		
    		    public String getName() 
    		        return name;
    		    
    		
    		    public int getAge() 
    		        return age;
    		    
    		
    

    pupil.java

    public class pupil extends student
    				    private double grades;
    				
    				    public pupil()
    				
    				    public pupil(String name, int age,double grades)
    				        super(name,age);
    				        setGrades(grades);
    				    
    				
    				    public void setGrades(double grades) 
    				        this.grades = grades;
    				    
    				
    				    public double getGrades() 
    				        return grades;
    				    
    				
    

    testing.java

    public class testing 
    	    public static void main(String[] args) 
    	        pupil p = new pupil("小明",18,100.00);
    	        System.out.printf("name:%s,\\tage:%d,\\tgrades:%.2f",p.getName(),p.getAge(),p.getGrades());
    	    
    	
    

  4. 调用方法的顺序:

    1. 先找本类,如果有,则调用

    2. 如果没有,则找父类,并可以调用,则调用

    3. 如果父类没有,则继续找父类的父类,整个规则相同,直到Object类

    4. tips:
      a. 如果查找方法的过程中,找到了,但是不能访问,则报错
      b. 如果查找方法的过程中,没有找到,则提示方法不存在
      c. super.cal()是直接查找父类,其他规则一样(从b步骤开始)
      d. 当子类中有和父类中的成员(属性和方法)重名是,为了访问父类的成员,必须通过super,如果没有重名,使用super、this、直接访问时一样的效果
      e. super的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用super取访问爷爷类的成员,如果多个基类含有相同的属性名,则使用super访问遵循就近原则,A——>B——>C,同时也需要遵守访问权限的相关规则

    5. super和this的比较

3.2 继承

3.2.1 概念

  1. 子类继承了所有类的属性和方法,非私有属性和方法可以在子类中直接访问,但是私有属性不能再子类直接访问,要通过公共的方法访问
  2. 子类必须调用父类的构造器,完成父类的初始化
  3. 当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会调用父类的无参构造器
  4. 如果父类没有提供无参构造器,则必须在子类的构造器中使用super去指定使用父类的哪个构造器完成对父类的初始化工作,否则编译不通过
  5. 如果希望指定去调用父类的某个构造器,则显式的调用一下
  6. super在使用时,需要放在构造器第一行
  7. super和this都只能放在构造器第一行,因为这两个方法不能共存在同一个构造器中
  8. java所有类都是Object类的子类,Object是所有类的基类
  9. 父类构造器的调用不限于直接父类,将一直往上追溯直到Object类(顶级父类)
  10. 子类最多只能继承一个父类(指直接继承),即java中是单继承方式
  11. 不能滥用继承,子类和父类之间必须满足is-a的逻辑关系

3.2.2 继承的本质

当子类对象创建好后,建立查找的关系

public class ExtendsTheory
    public static void main(Strings[] agrs])
        Son son = new Son();    
    

class GrandPa
    String name = "爷爷";
    String hobby = "旅游";

class Father extends GrandPa
    String name = "爸爸";
    int age = 39;

class Son extends Father
    String name = "儿子";

  • 由于只创建一个Son对象,故堆中只划分了一块区域
  • 然后再在方法区创建按照 Object——>Son的顺序创建对象
  • 调用方法时按照 本类——>Object的顺序进行查找(继承的顺序)

3.2.3 方法重写/覆盖

  1. 子类方法的形参列表,方法名要和父类的一样
  2. 子类方法的返回类型和父类方法返回类型一样,或者是父类返回类型的子类
    eg:父类:返回类型Object
    子类:返回类型String
  3. 子类方法不能缩小父类方法的访问权限:public>protected>默认>private

3.2.3.1 方法重载和方法重写的比较

四、多态

4.1 方法的多态

重写+重载

4.2 对象的多态

  1. 一个对象的编译类型和运行类型可以不一致

  2. 编译类型在定义对象时就确定了,不能改变

  3. 运行类型是可以变化的

  4. 编译时类型由声明该变量时使用的类型决定,编译时引用变量只能调用其编译类型所具有的方法。

  5. 运行时类型由实际赋给该变量的对象决定。

  6. 编译类型看定义时=的左边,运行类型看=的右边

    //Animal.java
    public class Animal 
        private String name;
        public Animal()
        public void cry()
            System.out.println("cyr:animal");
        
    
    //Dog.java
    public class Dog extends Animal
        public void cry() 
            System.out.println("cry dog");
        
    
    //Cat.java
    public class Cat extends Animal
        public void cry()
            System.out.println("cry: cat");
        
    
    //PolyObject.java
    public class PolyObject 
        public static void main(String[] args)
            Animal animal = new Dog(); //编译类型:Animal,运行类型Dog
            animal.cry();
            animal = new Cat();//编译类型:Animal,运行类型cat
            animal.cry();
        
    
    

    运行结果:

  7. 案例

    //Animal.java
    public class Animal 
        private String name;
        public Animal(String name)
            this.name=name;
        
        public String getName()
            return this.name;
        
    
    //Dog.java
    public class Dog extends Animal
        public Dog(String name)
            super(name);
        
        public void cry() 
            System.out.println("cry dog:"+this.getName());
        
    
    //Food.java
    public class Food 
        private String name;
        public Food(String name)this.name=name;
        public String getName()
            return this.name;
        
    
    //Rice.java
    public class Rice extends Food
        public Rice(String name)
            super(name);
        
    
    //PolyObject.java
    public class PolyObject 
        public static void main(String[] args)
            Animal animal = new Dog("大黄");
            animal.cry();
            Food food = new Rice("黑米粥");
            Master master = new Master("杰西");
            master.feed(animal,food);
        
    
    

4.3 向上转型

  1. 前提:两个对象(类)存在继承关系

  2. 本质:父类的引用指向了子类的对象

  3. 语法:父类类型

    引用名=new 子类类型()
    Animal animal = new Dog();
    
  4. 特点:编译类型看左边,运行类型看右边

  5. 可以调用父类中的所有成员(需要遵循访问权限)

  6. 不能调用子类中特有成员

  7. 最终运行效果看子类的具体实现(即运行时,按照运行类型决定)

4.4 向下转型

  1. 语法:子类类型

    引用名 = (子类类型)父类引用;
    Cat cat = (Cat) animal; //但是要父类的引用必须是指向当前目标类型的引用
    
  2. 只能强转父类的引用,不能强转父类的对象

  3. 要求父类的引用必须指向的是当前目标类型的对象

  4. 可以调用子类类型中的所有成员

4.5 多态——属性

属性没有重写之说,属性的值看编译类型

4.6 多态——instanceOf

instanceOf比较操作符,用于判断对象的运行类型 是否为xx类型 或者 xx类型的子类型

4.7 动态绑定机制❤️

  • 当调用对象方法时,该方法会和该对象的 内存地址/运行类型 绑定
  • 当调用对象属性时,没有动态绑定机制,哪里声明,哪里使用

4.8 应用

4.8.1 多态数组

例1:

public class PolyArray 
    public static void main(String[] args)
        Person[] persons = new Person[5];
        persons[0] = new Student("小明",100);
        persons[1] = new Student("大明",400);
        persons[2] = new Teacher("大强",20000);
        persons[3] = new Teacher("小强",50000);
        persons[4] = new Teacher("中强",90000);
        for(int i=0;i<persons.length;i++)
            persons[i].say();
            if(persons[i] instanceof Student)
                ((Student) persons[i]).study();
            else if(persons[i] instanceof  Teacher)
                ((Teacher) persons[i]).teach();
            else
                System.out.println("类型错误");
            
        
    

class Person 
    private String name;
    public Person(String name)
        this.name=name;
    
    public String getName() 
        return this.name;
    
    public void say()
        System.out.println(this.name);
    

class Student extends Person
    private double grades;
    public Student(String name,double grades)
        super(name);
        this.grades = grades;
    

    public double getGrades() 
        return grades;
    

    public void say()
        System.out.println("学生"+this.getName()+"成绩"+this.getGrades());
    

    public void study()
        System.out.println("学生"+this.getName()+"正在学习");
    

class Teacher extends Person
    private double salary;
    public Teacher(String name,double salary)
        super(name);
        this.salary = salary;
    

    public double getSalary() 
        return salary;
    
    public void say()
        System.out.println("教师"+this.getName()+"薪酬"+this.getSalary());
    
    public void teach()
        System.out.println("教师"+this.getName()+"正在教书");
    

4.8.2 例题

//Employee.java
public class Employee 
    private String name;
    private double salary;
    public Employee(String name, double salary)
        this.name=name;
        this.salary=salary;
    
    public String getName() 
        return name;
    
    public double getSalary() 
        return salary;
    
    public double getAnnual()
        return this.salary*12;
    


//CommenEmployee.java
public class CommenEmployee extends Employee
    public CommenEmployee(String name, double salary)
        super(name,salary);
    
    public void work()
        System.out.println("普通员工:"+super.getName()+"正在工作");
    


//Manager.java
public class Manager extends Employee
    private double bonus;
    public Manager(String name,double salary,double bonus)
        super(name,salary);
        this.bonus = bonus;
    

    public double getBonus() 
        return bonus;
    

    public void manage()
        System.out.println("经理:"+super.getName()+"正在管理");
    


//PolyParametersTesting.java
public class PolyParameterTesting 
    public void showEmpAnnual(Employee e)
        double salary = e.getSalary();
        if(e instanceof Manager)
            salary+=((Manager) e).getBonus();
        
        System.out.println(salary);
    
    public void testWork(Employee e)
        if(e instanceof CommenEmployee)
            ((CommenEmployee)e).work();
        else if(e instanceof Manager)
            ((Manager)e).manage();
        else 
            System.out.println("类型出错");
        
    


//PolyParameters.java
public class PolyParameter 
    public static void main(String[] args)
        Employee[] es = new Employee[2];
        es[0] = new CommenEmployee("员工",1000);
        es[1JAVA06 封装继承多态 总结(初级)

Java初级开发面试被问到封装多态继承直接原地撸代码,要我明天入职滴滴?

Java初级面试题

Java初级面试题

JavaSE学习总结——封装,继承,多态很简单

java中封装,继承,多态,接口学习总结