基本介绍

面向对象编程有三大特征:封装、继承和多态。

封装(Encapsulation)

封装介绍

        封装是指属性私有化,就是把抽象出的数据【属性】和对数据的操作【方法】封装在一起,数据被保护在内部,程序的其他部分只有通过被授权的操作【方法】,才能对数据进行操作。

封装的理解和好处

  • 隐藏实现细节:方法(连接数据库)《--调用(传参),简化编程。
  • 增强数据安全性,不能让其他用户随意访问和修改数据。

封装的实现步骤

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

pulic void setXxx(类型  参数名){//Xxx表示某个属性

        //加入数据验证的业务逻辑

        属性=参数名;

}

pulic 返回数据类型 getXxx(类型  参数名){//权限判断,Xxx表示某个属性

        return xx;

}

private String name;
    
    public void setName(String name) {
        this.name = name;
    }
    
    public String getName() {

        return name;
    }

Java基础——面向对象三大特征_子类

this关键字

         java虚拟机会给每个对象分配this,代表当前对象。

  1. this关键字可以用来访问本类的属性、方法、构造器。
  2. this用于区分当前类的属性和局部变量。
  3. 访问当前对象的属性语法:this.属性。
  4. 访问当前对象成员方法的语法:this.方法(参数列表)。
  5. 访问当前对象构造器语法:this(参数列表);注意只能在构造器中使用(即只能在构造器中访问另一个构造器,必须放在第一条语句)。
  6. this不能在类定义的外部使用,只能在类定义的方法中使用。
  7. 封装对象的属性的时候,经尝会使用this关键字。
  8. 当getter和setter函数参数名和成员函数名重合的时候,可以使用this区别。如:

public void setName(String name) {
        this.name = name;
    }

继承(Extend)

继承介绍

        继承的目的是解决代码复用,让我们的编程更加接近人类思维。当多个类存在相同属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有子类不需要重新定义这些属性和方法,只需要通过extends来声明继承父类即可。

 继承的基本语法

class 子类 extends 父类{

}

  • 子类继承后就会自动拥有父类定义的属性和方法
  • 父类又叫超类,基类。
  • 子类又叫派生类。

继承的好处

  1. 代码的复用性提高(子类拥有父类定义的属性和方法,除private修饰的除外)。
  2. 代码的扩展性和维护性提高。

继承的细节

  1. 子类继承了所有的属性和方法,非私有的属性和方法可以在子类中直接访问,但是私有属性和方法不能在子类中直接访问,要通过父类提供公共的方法去访问。
  2. 子类必须调用父类的构造器,完成父类的初始化。
  3. 当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造,如果父类没有提供无参构造,则必须在子类的构造器中用super()去指定使用父类的哪个构造器完成对父类的初始化工作,否则编译不通过。
  4. 如果希望指定去调用父类的某个构造器,则显示的调用一下:super(参数列表)。
  5. super在使用时,必须放在构造器第一行(这点与this一样,但super与this不共存)。
  6. java所有类都是object类的子类,object是所有类的基类。
  7. 父类构造器的调用不限于直接父类,可以一直往上追溯到知道object类(顶级父类)。
  8. 子类最多只能继承一个(指直接继承),即Java是单继承机制,如果想让A类继承B类和C类,【B继承C、A继承B】。
  9. 不能滥用继承,子类和父类之间必须满足is-a的逻辑关系。
class Person{
    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {//构造方法重载
        this.name = name;
        this.age = age;
    }

    public String say(){
        return "name='" + name + '\'' +
                ", age=" + age;
    }
}
class Student extends Person{
    private String id;
    private double score;
    public Student(){
        //默认调用super(),即Person类的无参构造。
    }

    public Student(String name, int age, String id, double score) {
        super(name, age);//指定调用父类有参构造
        this.id = id;
        this.score = score;
    }


    public String say(){//方法重写
        return super.say()+'\t'+"id="+id+'\''+
                ",score="+score;
    }
}

Java基础——面向对象三大特征_构造器_02

super关键字

        super代表父类的引用,用于访问父类的属性、方法、构造器。

  1. 访问父类的属性,但不能访问父类的private属性:super.属性名;
  2. 访问父类的方法,但不能访问父类的private方法:super.方法名(参数列表);
  3. 访问父类的构造器:super(参数列表);只能放在构造器第一句,且只能有一句。

super细节

  • 当子类中有和父类中的成员(属性和方法)重名时,为了访问父类的成员,必须通过super。如果没有重名,使用super、this、直接访问效果一样。
  • super的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以直接使用super去访问爷爷类的成员;如果多个基类(上级类)中都有相同的成员,使用super访问遵循就近原则。A—》B—》C,当然也需要遵循访问权限的相关规则。

super和this比较

Java基础——面向对象三大特征_构造器_03

多态(Polymiorph)

多态介绍

        多态即多种状态,方法或对象具有多种形式。同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果,这就是多态性。简单的说:就是用基类的引用指向子类的对象。是面向对象的第三大特征,多态建立在封装和继承既相互之上。

多态的具体体现

 1.方法的多态

重载(Overloading)

        重载是允许在同一个类里面,多个同名方法存在,但要求形参列表不同。返回类型可以相同也可以不同。每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。最常用的地方就是构造器的重载。

  • 方法名:必须相同。
  • 形参列表:必须不同(形参类型或个数或顺序,至少有一样不同,参数名无要求)。
  • 返回类型:无要求。

其实简单而言:重载就是对于不同的情况写不同的方法。 比如,同一个类中,写不同的构造函数用于初始化不同的参数。

package com.study.srv.demo3;

public class Demo05 {
    public static void main(String[] args) {
        Demo05 demo05 = new Demo05();
        demo05.test();
        demo05.test("jack",23);
        demo05.test(23,"jack");
        System.out.println(demo05.test("jack"));
    }
    public void test(){//无参
        System.out.println("无参无返回值!");
    }
    public void test(String name,int age){//有参
        System.out.println("有参无返回值:"+name+age);
    }
    public void test(int age,String name){//参数顺序不同
        System.out.println("有参但参数顺序不同无返回值:"+age+name);
    }
    public String test(String name){//有返回值,但是一定要参数不同,才能算重载
        return "有参有返回值:"+name;
    }
}

重写(Override)

        简单来说:方法覆盖(重写)就是子类中有一个方法和父类中的某个方法的名称、返回类型、参数一样,那么我们就说子类的这个方法覆盖了父类的方法。

  1. 方法名必须相同,返回值类型必须相同。
  2. 参数列表必须相同。
  3. 子类方法不能缩小父类方法的访问权限。例如:如果父类的一个方法被声明为public,那么在子类中重写该方法就不能声明为protected。
  4. 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为private和final的方法。
  5. 构造方法不能被重写。
package com.study.srv.demo3;

public class Demo01 {
    public static void main(String[] args) {
        Person person = new Person("李宁",24);
        System.out.println(person.say());
        Student student = new Student("向前",21,"2011301101",87.2);
        System.out.println(student.say());
    }
}
class Person{
    private String name;
    private int age;
    public Person() {
    }

    public Person(String name, int age) {//构造方法重载
        this.name = name;
        this.age = age;
    }

    public String say(){
        return "name='" + name + '\'' +
                ", age=" + age;
    }
}
class Student extends Person{
    private String id;
    private double score;

    public Student(){
        //默认调用super(),即Person类的无参构造。
    }

    public Student(String name, int age, String id, double score) {
        super(name, age);//指定调用父类有参构造
        this.id = id;
        this.score = score;
    }


    public String say(){//方法重写
        return super.say()+'\t'+"id="+id+'\''+
                ",score="+score;
    }
}

名称

发生范围

方法名

形参列表

返回类型

修饰符

重载(overload)

本类

必须一样

形参类型或个数或顺序,至少有一样不同

无要求

无要求

重写(Override)

父子类

必须一样

相同

子类重写的方法,返回的类型和父类返回的类型一致,或者是其子类

子类方法不能缩小父类方法的访问权限

 2.对象的多态

        父类的引用可以指向本类的对象;

   父类的引用可以指向子类的对象;

  1. 一个对象的编译类型和运行类型可以不一致。
  2. 编译类型在定义对象时就确定了,不能改变。
  3. 运行类型可以变化。
  4. 编译类型看定义时=号的左边,运行类型看=号的右边。

多态细节

        多态的前提是:两个对象(类)存在继承关系。

多态向上转型:

  • 本质:父类的引用指向了子类的对象。
  • 语法:父类类型   引用名=new 子类类型();
  • 特点:编译类型看左边,运行类型看右边。  可以调用父类中的所有成员(需遵守访问权限),不能调用子类中特有成员;最终运行效果看子类具体实现。

多态向下转型:

  • 语法:子类类型   引用名= (子类类型) 父类引用;
  • 只能强转父类的引用,不能强转父类的对象。
  • 要求父类的引用必须指向的是当前目标类型的对象。
  • 当向下转型后,可以调用子类类型中所有的成员。