栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java之面向对象三大特性简介

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java之面向对象三大特性简介

面向对象三大特性简介
  • 前言
  • 一、继承
    • 1、继承的主要作用
    • 2、继承的实现
    • 3、继承使用要点
    • 4、方法的重写Override
    • 5、Final关键字
    • 6、继承和组合
  • 二、Object类
    • 1、Object类基本特性
    • 2、toString方法
    • 3、== 和equals方法
    • 4、 super关键字
    • 5、继承树的追溯
  • 三、封装
    • 1、封装的作用
    • 2、封装的实现-使用访问控制符
    • 3、封装使用的细节
  • 四、多态
    • 1、多态概念和实现
    • 2、对象的转型
  • 总结
  • 参考文献

前言

面向对象三大特性简介,继承、封装、多态。

一、继承 1、继承的主要作用

1)代码复用,更加容易实现类的扩展,类之间又有很多共性,避免写更多冗余的代码。
2)方便对现实世界建模,因为现实世界大多数都是继承关系。

2、继承的实现

用extends来实现,class A extends B,A 扩展了 B。

public class Person {
    String name;
    Person friend;

    public static void main(String[] args) {
        Person p1 = new Person();
        Person p2 = new Person();
        p1.friend = p2;
        p2.friend = p1;
        p1 = p2 = null;
    }
}
class Teacher extends Person{
    //Teacher除了有name和朋友,还有所属学校
    //String name;
    //Person friend;
    String universityName;
}
3、继承使用要点

1)为了避免多继承造成复制的继承链,系统难于维护,Java中只能单继承。
2)Java类中没有多继承,但接口有多继承。
3)子类继承父类,能得到父类除构造器的成员变量和成员方法,但不见得可以直接访问(比如父类的私有属性和方法)
4)如果一个Java类没有显示继承,则会隐式继承java.lang.Object类。
5)可通过instanceof来判断类的类型。
p1 instanceof Person,结果为Boolean变量

4、方法的重写Override

子类重写父类的方法,可以通过自身的行为替代父类的行为。方法的重写是实现多态的必要条件。
三特点
1)“==”,方法名、形参列表相同。
2)“<=”,子类异常要是父类异常的子类或者本异常。这跟动态绑定有关。
3)">=",访问权限,子类大于父类。
之类重写的方法前面给的修饰权限要大于等于父类。public > protected>default>private.
注:属性没有这一说法,子类写了一个同名属性,没有这种权限关系,调属性时,先调子类属性,没有再根据权限来调父类属性。如果是父类对象调同名属性,那只能调父类的属性。没有所谓的属性运行时多态。

public class Person {
    String name;
    Person friend;

    public void sleep(){
        System.out.println("睡觉");
    }
    public static void main(String[] args) {
        Person p1 = new Person();
        Person p2 = new Person();
        p1.friend = p2;
        p2.friend = p1;
        p1 = p2 = null;
    }
}
class Teacher extends Person{
    //Teacher除了有name和朋友,还有所属学校
    String universityName;

    //不一样的睡觉
    @Override
    public void sleep(){
        System.out.println("去办公室");
        super.sleep();
    }
}
5、Final关键字

1)FInal修饰变量,该变量变为常量,一经复制,就不能再修改。
2)Final修饰方法,该方法不能被重写,但是可以重载。
3)Final修饰类,该类不能被扩展,即继承,如String、Math类。

final class Teacher extends Person{
    //Teacher除了有name和朋友,还有所属学校
    String universityName;

    //不一样的睡觉
    @Override
    public void sleep(){
        System.out.println("去办公室");
        super.sleep();
    }
    final int MOD = 4;
    public final int mod(int n){
        return n % MOD;
    }
}
6、继承和组合

组合)将父类对象作为子类的属性,通过这个父类属性来调用父类的属性和方法,更加灵活。

class Teacher {
    
    String universityName;
    Person p;
    //不一样的睡觉
    
    final int MOD = 4;
    public final int mod(int n){
        return n % MOD;
    }

    public static void main(String[] args) {
        Teacher t = new Teacher();
        t.p = new Person();
        t.p.sleep();
    }
}

总结)组合虽然灵活,但也要分情况,为了更好的建模,当属于is-a的时候,就使用继承;当属于has a 的时候,就使用组合。
如Teacher is a Person更加恰当,所以用继承,能更好的建模。
如Computer has a Chip,此时使用组合更恰当。因为电脑虽然要用芯片里的方法,但是继承它不太合理,逻辑混乱。

二、Object类 1、Object类基本特性

Object类是所有类的根基类,所有Java类的根基类都是Object类,继承了Object类的属性和方法,但因权限问题,不一定能全部访问。

2、toString方法

JDK Object类的源码及注释,大概意思就是返回类名+@+对象地址

    
    public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

可在类中重写toString方法,具有自己的独特性,而不是只有地址。

public class Person {
    String name;
    Person friend;

    public void sleep(){
        System.out.println("睡觉");
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + ''' +
                ", friend=" + friend +
                '}';
    }
    public static void main(String[] args) {
        Person p1 = new Person();
        //输出p1,会自动调p1.toString()
        System.out.println(p1);
    }
}
3、== 和equals方法
    public boolean equals(Object obj) {
        return (this == obj);
    }

在Object中,equals的原理就是==,它比较的是两个对象的地址,而如果两个对象的属性相等时,我们认为它俩相等,此时需重写equals方法。

@Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return name.equals(person.name) &&
                friend.equals(person.friend);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, friend);
    }

name去比较的时候也用了equals,String的equals也是重写了的,注释及源码如下。

    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String aString = (String)anObject;
            if (coder() == aString.coder()) {
                return isLatin1() ? StringLatin1.equals(value, aString.value)
                                  : StringUTF16.equals(value, aString.value);
            }
        }
        return false;
    }
4、 super关键字

可以看做直接父类的引用。
构造函数)在子类的构造函数中,如果没有显示的调用super(…),会隐式调用super()

public Person(){
        System.out.println("调用Person的构造器");
    }
package com.xhu.java;

public class Teacher extends Person {

    String universityName;
    Person p;
    //不一样的睡觉
    public Teacher(){
        System.out.println("调用Teacher构造器");
    }
    final int MOD = 4;
    public final int mod(int n){
        return n % MOD;
    }

    public static void main(String[] args) {
        System.out.println("准备new一个对象");
        Teacher t = new Teacher();
    }

}

5、继承树的追溯


这是继承树的追溯过程。
先构建父类,然后父类执行构造函数,赋值操作,再构建子类对象,然后赋值操。

三、封装

合理的封装让外部调用方便,也便于自己修改代码。

1、封装的作用

“高内聚、低耦合”,高内聚:内部数据操作细节完成,不允许外部干涉;低耦合:只暴露少量方法给外部使用,方便外部调用。
封装的优点:
1)代码的安全性
2)代码的复用性
3)高内聚:封装细节,便于修改内部代码,从而提高可维护性。
4)低耦合:简化外部调用,便于调用者使用,从而便于协作。

2、封装的实现-使用访问控制符


对于protected,若子类和父类在同一包中,子类可以访问父类的protected成员,也可以访问父类任意对象的protected成员;若子类和父类不在同一包中,子类只可以访问父类的protected成员,不能访问任意父类对象的protected成员。

class Person {
    protected String name;
}

下面的访问属于访问父类的projected的成员:

public class Teacher extends Person {

    String universityName;
   
    public void testProtected(){
        System.out.println(super.name);
    }
  

}

下面的访问属于访问父类任意对象的projected的成员:

public class Teacher extends Person {

    String universityName;
  
    public static void main(String[] args) {
        Teacher t = new Teacher();
        System.out.println(t.name);
    }

}
3、封装使用的细节

1)对于成员变量,一般是private修饰,然后提供get、set方法来访问。
2)本类提供给它类调用的方法设为public,本类中的辅助方法,用private修饰。
JavaBean的封装演示:

package com.xhu.java;

public class Teacher extends Person {

    private String universityName;
    private boolean flag;

    public String getUniversityName() {
        return universityName;
    }

    public void setUniversityName(String universityName) {
        this.universityName = universityName;
    }

    public boolean isFlag() {
        return flag;
    }
 	public Teacher(){
        System.out.println("调用Teacher构造器");
    }
    public Teacher(String universityName) {
        this.universityName = universityName;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "universityName='" + universityName + ''' +
                ", name='" + name + ''' +
                ", friend=" + friend +
                '}';
    }
}

四、多态 1、多态概念和实现

由于继承与方法重写的原因,多态是指调用同名重载方法,对象不同可能会有不同的行为。
比如Person类的睡觉就是简单的睡觉,而继承它的Teacher类和Student类的sleep()方法不同。

Person p1 = new Teacher();
Person p2 = new Student();
p1.sleep();
p2.sleep();
//out
//老师的休息
//学生的休息

多态)多态是方法的多态,不是属性的多态。
多态存在的三个条件)继承、方法重写、父类引用指向之类对象。
多态出现)父类引用指向子类对象后,父类引用调用子类重写的方法,多态出现。
为什么要用父类引用指向子类对象?当一个类被很多类继承时,传入一个子类对象,然后调一个同名函数,此时就要判断这个对象到底是那个子类对象,而此时可以用父类接收对象,通过运行时的多态来决定具体调那个子类的重写函数(通过instanceof来判断的)。此时代码就简介了很多。
需要重载多个函数。

public void test(Teacher t){
        t.sleep();
    }
    public void test(Student s){
        s.sleep();
    }
    public void test(Postgraduate po){
        po.sleep();
    }

通过多态,简化代码

public void test(Person p){
        p.sleep();
    }
2、对象的转型
public static void main(String[] args) {
		//编译时,只认p为Person对象。
        Person p = new Teacher();//向上类型转化,自动完成。
        Teacher t = (Teacher) p;//向下类型转化,强制完成。
    }

但是为了防止异常,我们需要手动处理一下:

public static void main(String[] args) {
        Person p = new Teacher();//向上类型转化,自动完成。
        Teacher t = null;
        if(p instanceof Teacher)
            t = (Teacher) p;//向下类型转化,强制完成。
    }
总结

1)封装
2)继承
3)多态

参考文献

[1] Java SE 高淇

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/444824.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号