java——面向对象是三大特征

一、封装

1.1、封装(encapsulation)

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

1.2、封装的理解和好处

1、隐藏实现细节:方法(连接数据库)<--调用(传入参数..)

2、可以对数据进行验证,保证安全合理

1.3、封装的实现步骤 (三步)

1、将属性进行私有化private 【不能直接修改属性】

2、提供一个公共的(public)set方法,用于对属性判断并赋值

public void setXxx(类型参数名){//Xxx表示某个属性
    //加入数据验证的业务逻辑
    属性=参数名
}

3、提供一个公共的(public)get方法,用于获取属性的值

public数据类型getXxx(){//权限判断,Xxx某个属性
    return xx;
}

注:

1)自己写 setXxx 和 getXxx 太慢,我们使用构造器快捷键alt+insert-->Getter and Setter

2)可以将 set 方法写在构造器(一个无参(继承调用) 一个有参+set)中,这样仍然可以限制

二、继承extends

2.1、基本介绍和示意图

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

2.2、继承的基本语法

class 子类 extends 父类{
}

1、子类就会自动拥有父类定义的属性和方法

2、父类又叫超类,基类

3、子类又叫派生类

2.3、继承给编程带来的便利

1、代码的复用性提高了

2、代码的扩展性和维护性提高了

2.4、继承的注意事项和使用细节

1、子类继承了所有的属性和方法,非私有的属性和方法可以在子类直接访问, 但是私有属性和方法不能在子类直接访问,要通过父类提供公共的方法去访问

2、子类必须调用父类的构造器,完成父类的初始化

3、当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用 super 去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译不会通过

4、如果希望指定调用父类的某个构造器,则显式的调用一下 : super(参数列表)

5、super 在使用时,必须放在构造器第一行(super 只能在构造器中使用)

6、super() 和 this() 都只能放在构造器第一行,因此这两个方法不能共存在一个构造器

7、java 所有类都是 Object 类的子类, Object 是所有类的基类,顶级类

8、父类构造器的调用不限于直接父类!将一直往上追溯直到 Object 类(顶级父类)

9、子类最多只能继承一个父类(指直接继承),即 java 中是单继承机制

思考:如何让 A 类继承 B 类和 C 类? 【A 继承 B, B 继承 C】

10、不能滥用继承,子类和父类之间必须满足 is-a 的逻辑关系

2.5、继承的本质分析(重要)

查找关系来返回信息

A) 首先看子类是否有该属性

B) 如果子类有这个属性,并且可以访问,则返回信息

C) 如果子类没有这个属性,就看父类有没有这个属性(如果父类有该属性,并且可以访问,就返回信息..)

D) 如果父类没有就按照(3)的规则,继续找上级父类,直到 Object..

提示:如果查找方法的过程中,找到了,但是不能访问, 则报错, cannot access

如果查找方法的过程中,没有找到,则提示方法不存在

三、多态

3.1、基本介绍:

方法或对象具有多种形态。是面向对象的第三大特征,多态是建立在封装和继承基础之上的。

3.2、多态的具体体现

1、方法的多态:重写和重载就体现多态

2、对象的多态 (核心,困难,重点)

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

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

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

4)编译类型看定义时“=”号的左边,运行类型看“=”号的右边

Animal animal = new Dog();//【animal 编译类型是Animal,运行类型Dog】
animal=new Cat()://【animal的运行类型变成了Cat,编译类型仍然是Animal】

3.3、多态的注意事项

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

3.3.1、多态的向上转型

1、本质:父类的引用指向了子类的对象

2、语法:父类类型 引用名=new 子类类型();

3、特点:编译类型看左边,运行类型看右边。

A)可以调用父类中的所有成员(需遵守访问权限),不能调用子类中特有成员;(因为在编译阶段,能调用哪些成员,是由编译类型来决定的)

B)最终运行效果看子类(运行类型)的具体实现!(调用方法时,按照从子类(运行类型)开始查找方法,然后调用,规则我前面我们讲的方法调用规则“查找关系来返回信息”一致)

3.3.2、多态向下转型

1、语法:子类类型 引用名=(子类类型)父类引用;

2、只能强转父类的引用,不能强转父类的对象

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

Animal animal = new Cat();
Cat cat = (Cat) animal;
Dog dog = (Dog) animal; //错误×

4、当向下转型后,可以调用子类类型中所有的成员

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

//假设Base 为父类,Sub 为子类
Base base = new Sub();//向上转型
System.out.println(base.count);// ? 看编译类型Base里的count值
Sub sub = new Sub();
System.out.println(sub.count);// ? Sub里的count值

4、instanceOf 比较操作符(对象 instanceOf XX),用于判断对象的运行类型是否为 XX 类型或 XX 类型的子类型

5、对象.getClass():获得该对象的运行类型

3.4、java的动态绑定机制

1、当调用对象方法的时候,该方法会和该对象的内存地址/运行类型绑定

2、当调用对象属性时,没有动态绑定机制,哪里声明,那里使用

3.5、多态的应用

3.5.1、多态数组

数组的定义类型为父类类型,里面保存的实际元素类型为子类类型

应用实例:现有一个继承结构如下:要求创建 1 个 Person 对象、2 个 Student 对象和 2 个 Teacher 对象, 统一放在数组中,并调用每个对象say 方法

public class Person {//父类
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String say() {//返回名字和年龄
        return name + "\t" + age;
    }
}
public class Student extends Person {
    private double score;

    public Student(String name, int age, double score) {
        super(name, age);
        this.score = score;
    }

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }

    //重写父类say
    @Override
    public String say() {
        return "学生 " + super.say() + " score=" + score;
    }

    //特有的方法
    public void study() {
        System.out.println("学生 " + getName() + " 正在学java...");
    }
}
public class Teacher extends Person {
    private double salary;

    public Teacher(String name, int age, double salary) {
        super(name, age);
        this.salary = salary;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    //写重写父类的say方法
    @Override
    public String say() {
        return "老师 " + super.say() + " salary=" + salary;
    }

    //特有方法
    public void teach() {
        System.out.println("老师 " + getName() + " 正在讲java课程...");
    }
}
public class PloyArray {
    public static void main(String[] args) {
        Person[] persons = new Person[5];
        persons[0] = new Person("jack", 20);
        persons[1] = new Student("mary", 18, 100);
        persons[2] = new Student("smith", 19, 30.1);
        persons[3] = new Teacher("scott", 30, 20000);
        persons[4] = new Teacher("king", 50, 25000);
        //循环遍历多态数组,调用say
        for (int i = 0; i < persons.length; i++) {
            //老师提示: person[i] 编译类型是 Person ,运行类型是是根据实际情况有JVM来判断
            System.out.println(persons[i].say());//动态绑定机制
            //使用 类型判断 + 向下转型.
            if(persons[i]  instanceof  Student) {//判断person[i] 的运行类型是不是Student
                Student student = (Student)persons[i];//向下转型
                student.study();
                //也可以使用一条语句 ((Student)persons[i]).study();
            } else if(persons[i] instanceof  Teacher) {
                Teacher teacher = (Teacher)persons[i];
                teacher.teach();
            } else if(persons[i] instanceof  Person){
                //System.out.println("你的类型有误, 请自己检查...");
            } else {
                System.out.println("你的类型有误, 请自己检查...");
            }

        }

    }
}

3.5.2、多态参数

方法定义的形参类型为父类类型,实参类型允许为子类类型

四、super 关键字

4.1、基本介绍

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

4.2、基本语法

1、访问父类的属性,但不能访问父类的private属性àsuper.属性名;

2、访问父类的方法,不能访问父类的private方法àsuper.方法名(参数列表);

3)访问父类的构造器:super(参数列表);只能放在构造器的第一句,只能出现一句

4.3、super 的注意事项和使用细节

1、调用父类的构造器的好处(分工明确,父类属性由父类初始化,子类的属性由子类初始化)

2、当子类中有和父类中的成员(属性和方法)重名时,为了访问父类的成员,必须通过super。如果没有重名,使用super、this、直接访问是一样的效果

3、super的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用super去访问爷爷类的成员;如果多个基类(上级类)中都有同名的成员,使用super访问遵循就近原则。A->B->C,当然也需要遵守访问权限的相关规则

五、super 和 this 的比较

5.1、super关键字

见上

5.2、this关键字

七、this关键字

5.3、super 和 this 的比较

No.

区别点

this

Super

1

访问属性

访问本类中的属性,如果本类没有此属性则从父类中继续查找

从父类开始查找属性

2

调用方法

访问本类中的方法,如果本类没有此方法则从父类继续查找

直接从父类开始查找方法

3

调用构造器

调用本类构造器,必须放在构造器的首行

调用父类构造器,必须放在子类构造器的首行

4

特殊

表示当前对象

子类中访问父类对象

  • 18
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值