Java面向对象(OOP)高级

Java面向对象高级-面向对象思想三大特征:封装、继承、多态

一、封装

我们日常使用的电脑主机,把cpu、内存、主板等都封装到机箱里面去。假如没有机箱的话就会导致主机、主板等全部都散落在一处,然后开机没有开机按钮,那么需要我们直接操作接跳线才能把电脑开启,这样的话假如操作不慎的话,会让机器损坏危险
如果用机箱封装起来的话,那么就不需要这样做了,体现了封装的安全性

你拿电脑去加内存条,可以直接给电脑维修的人,等他加好内存之后,你拿到的还是那个机箱,里面发生了怎样的变化你不知道,封装的第二好处就是变化隔离

在机箱里面提供一个开机按钮,就不需要你直接使用跳线来开机,体现了封装的-便于使用的特性。

只要机箱提供了一个开机的功能,然后无论这个机箱拿到哪里去,都可以使用这个开机的功能,体现了封装的-重复性的特性。

1、不使用封装

创建一个Employee类,定义姓名、工号、性别的成员变量,和工作的方法,成员使用public进行修饰
创建Employee对象,并对成员进行赋值,最后调用对象中工作的方法

代码案例

package cn.com.example6;

public class Employee {

    public int id;

    public String name;

    public String sex;


    public void handlerWork(){
        System.out.println("name:"+name+",id:"+id+",sex:"+sex);
    }


    public static void main(String[] args) {

        Employee employee = new Employee();

        employee.id = 1001;
        employee.name = "admin";
        employee.sex = "不是人";

        employee.handlerWork();

    }
}

如果不使用封装,很容易赋值错误,并且任何人都可以更改,造成信息的不安全
解决:使用封装

2、封装的实现

类中的属性访问修饰符为private,不能使用对象名.属性名的方式直接访问对象的属性。

public访问修饰符,公共的,谁都可以访问
private访问修饰符,私有的,只有自己可以访问【在自己的类中可以访问,在类外部不能访问】
如果想让外部类访问,那么我们可以提供一些方式供外部访问【get获取、set设置】【从直接访问更改为间接访问,从被动更改为主动】

代码案例

package cn.com.example6;

public class Employee {

    private int id;

    private String name;

    private String sex;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public void handlerWork(){
        System.out.println("name:"+name+",id:"+id+",sex:"+sex);
    }


    public static void main(String[] args) {

        Employee employee = new Employee();

        employee.id = 1001;
        employee.name = "admin";
        employee.sex = "不是人";

        employee.handlerWork();

    }
}

3、封装的好处

  1. 隐藏了类的具体实现
  2. 操作简单
  3. 提高了对象数据的安全性

二、继承

继承:用于描述类和类之间的关系
比如:儿子类和父亲类,没有明显的描述出两个类之间的关系,所以不能直接说两个类有继承的关系

代码案例

package cn.com.example6;

public class Father {
    
    public String name;
    
    public int age;
    
    public void handlerMessage(){
        
        System.out.println("我是父亲");
    }
}



class Son{
    
    public String name;
    
    public int age;
    
    public void handlerMessage(){

        System.out.println("我是儿子");
    }
    
}

1、继承的特点

  1. 描述类和类之间的关系
  2. 降低类和类之间的重复代码【代码不会冗余】

2、extends关键字

extends:用于描述类与类之间的关系【继承】

语法:

public class 子类类名 extends 父类类名{

}

代码案例

package cn.com.example6;

public class Father {

    public String name;

    public int age;

    public void handlerMessage(){

        System.out.println("我是父亲");
    }


    public static void main(String[] args) {

        // 实例化子类对象
        Son son = new Son();

        // 调用继承的方法handlerMessage
        son.handlerMessage();


    }
}


// 子类继承了父类
class Son extends Father{

    public String name;

    public int age;


    public void handlerMethod(){

        System.out.println("子类的独有方法");
    }

}

注意事项:
1、类名的设定,被继承的类称之为父类,继承的类称之为子类
2、如果一个类没有显式的继承某个类,那么该类的父类是Object【基类、超类,所有类的父类】
3、子类一旦继承了父类,那么子类就继承了父类中所有非私有属性和方法,不能继承构造器 ,并且子类可以拥有独有的属性和方法
4、不要为了使用或简化某个功能而继承,java中只支持单继承
5、一个父类可以用多个子类,一个子类只能有一个父类【单继承】

在这里插入图片描述

3、super关键字

super:类似于this,用于指向子类对象中父类对象

语法:

super.属性名 // 父类属性【继承过来的】
super() // 调用父类构造器【无参、有参】

问题解决:

  1. 子类对象为什么可以访问父类的成员
    • this.y = y+x;有一个隐式的super super.x
  2. super关键字作用
    • 主要存在于子类方法中,用于指向子类对象中父类对象
    • 访问父类的属性、函数、构造函数
    • 执行子类构造器之前会先执行父类构造器:super()
  3. super定义
    • 如果没有显式的定义,那么系统会自动定义

注意:super()不能和this()一起使用,因为super()需要定义在第一行

代码案例

package cn.com.example6;

public class Father {

    public String name;

    public int age;

    public void handlerMessage(){

        System.out.println("我是父亲");
    }


    public static void main(String[] args) {

        // 实例化子类对象
        Son son = new Son();

        // 调用继承的方法handlerMessage
        son.handlerMessage();


    }
}


// 子类继承了父类
class Son extends Father{

    public String name;

    public int age;

    // 子类构造器
    public Son(){
        super(); // 调用无参构造器
    }
    

    public void handlerMethod(){

        System.out.println("子类的独有方法");
    }

}

4、继承内存剖析

在这里插入图片描述

通过以上内存图能看出,加载父类的属性和方法比子类的属性和方法提前加载进内存中,那么我们可以在实例化子类对象时直接对属性进行初始化

代码案例

package cn.com.example6;

public class Father {

    public String name;

    public int age;

    public Father() {
    }

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


    public static void main(String[] args) {

        // 实例化子类对象
        Son son = new Son("admin",22);

    }
}


// 子类继承了父类
class Son extends Father{
    
    // 赋值
    public Son(String name,int age){
        super(name,age);
    }

}

5、重写

假如子类继承过来的方法内部的功能不满足现有的需求,那么子类可以重新定义该方法,这种做法称之为重写。
重写(Override):方法名相同,参数类型或个数也相同,方法体不同

  • 重载和重写的区别
    1. 重载(Overload)
      • 规范:方法名相同,参数类型和参数个数不同
      • 定义位置:在本类中
    2. 重写(Override)
      • 规范:方法名相同,参数类型和参数个数也相同,方法体不同
      • 定义位置:在子类中

代码案例

package cn.com.example6;

public class Father1 {

    public void handlerMessage(){

        System.out.println("这是父类的方法");
    }
}



package cn.com.example6;

public class Son1 extends Father1{


    @Override
    public void handlerMessage() {

        System.out.println("这是子类的方法");
    }

    public static void main(String[] args) {


        Son1 son1 = new Son1();

        son1.handlerMessage(); // 这是子类的方法

    }
}


当方法被重写,子类调用的是重写后的,因为当继承过来的属性和方法在子类中被重新定义,那么继承过来的属性和方法将被隐藏,通过super关键字可调用。

三、instanceof关键字

instanceof关键字:属于比较运算符,用于判断一个对象是否是指定类的对象

代码案例

Person per = new Person();

System.out.println(per instanceof Person); // true

四、抽象类

当描述一个类的时候,如果不能确定功能方法如何定义,那么该功能方法就可以定义为抽象方法,一个类中只要有抽象方法,该类必须是抽象类

1、抽象类的特点

  • 有抽象方法的类,该类一定是抽象类
  • 抽象类不一定要有抽象方法
  • 抽象类不能使用new创建对象
  • 抽象方法没有方法体
  • 抽象类主要为了提高代码的复用性,让子类继承来使用【重写】
  • 编译器会强制子类实现抽象类的未实现的方法,也可以不实现,前提是子类中也要声明为抽象的

2、抽象的优点

  • 提高代码复用性,强制子类实现父类中没有实现的功能
  • 提高代码扩展性,便于后期的代码维护

3、抽象类不能创建对象,那么抽象类中是否有构造方法?

抽象类中一定有构造方法,主要为了初始化抽象类中的属性,通常由子类实现。

4、final和abstract是否可以同时修饰一个类?

一定不能同时修饰,抽象类中的抽象方法需要被子类重写,而final修饰的类不能被继承,以及final修饰的方法不能被重写

5、抽象类和普通类的区别

抽象类比普通类多了抽象方法以及不能实例化对象,其余的都一样

代码案例

package cn.com.example6;

// 抽象类
public abstract class AbstractFather {

    public String name;
    
    // 抽象方法
    public abstract void handlerMethod();
}


class Son2 extends AbstractFather{


    @Override
    public void handlerMethod() {
        
    }
}

五、接口

接口(interface):USB接口,主要用来拓展笔记本的功能,那么在java中的接口主要用来拓展类的功能,可以弥补java单继承的缺点,并且达到了解耦

1、接口概述

在这里插入图片描述

代码案例

// 铅笔类
public class Pencil {
}




// 橡皮接口
public interface Rubber {

  // 接口中只能定义常量
  public String name = "橡皮"; 

  // 接口中只能定义抽象方法
  public void handlerMessage();
  
}




// 带橡皮的铅笔继承了铅笔类实现了橡皮接口
public class PencilWithRubber extends Pencil implements Rubber{
}


2、接口默认修饰符

使用javap进行反编译,发现接口中的属性,默认修饰符:public static final,方法默认修饰符:public abstract

在这里插入图片描述

3、接口的特点

  1. 类实现接口可以通过implements实现,实现接口的时候必须把接口中的所有方法实现
  2. 一个类可以实现多个接口【多实现】
  3. 接口中定义的所有属性默认是public static final修饰,即静态常量,所以定义时必须赋值
  4. 接口中定义的方法不能有方法体,因为接口中定义的方法默认添加了public abstract
  5. 由于接口中的方法都是抽象,所以不能被实例化
  6. 对于接口而言,可以使用子类来实现接口中未被实现的功能方法
  7. 如果实现类中要访问接口中的成员,不能通过super关键字,因为两者没有显示的继承,可以使用接口名直接访问
  8. 接口没有构造方法

4、接口与类之间的关系

类与类之间的关系是继承,那么接口与类之间的关系是实现,非抽象类实现接口时,必须把接口中所有的方法都实现,类实现接口用implements关键字,类与接口之间是可以多实现【一个类可以实现多个接口】

5、接口与接口之间的关系

接口与接口之间的关系是继承,接口可以继承多个接口【多继承】
比如:在现实生活中,有部分同学在学校期间只会学习,但是有部分同学除了学习还会赚钱
在java中类之间是单继承
在java中是多继承【接口之间】
在java中是多实现【类与接口】

六、多态

多态:多种形态
比如:老师 => 员工=> 儿子

1、多态的好处

父类可以调用不同子类的函数,提高了代码的维护性和扩展性

在这里插入图片描述

2、多态的前提条件

  • 必须是继承管理
  • 子类必须重写
  • 向上转型
    • 子类对象向上转型给父类类型【核心】

语法:

父类类型 对象名 = new  子类构造器();

代码案例

package cn.com.example6;

public interface InterfaceFather {

    public void handlerEat();


    public static void main(String[] args) {


        // 实例化子类对象并且向上转型为父类引用
        InterfaceFather interfaceFather = new ClassSon();

        // 调用方法
        interfaceFather.handlerEat();
    }

}


class ClassSon implements InterfaceFather{


    @Override
    public void handlerEat() {

        System.out.println("这是儿子吃的程序");
    }
}

注意:
1、子类一旦向上转型为父类引用,那么父类引用只能调用父类所具备的属性和方法,子类独有的不允许调用
2、当父类和子类具有相同的非静态成员变量,那么在多态下访问的是父类的成员变量
3、当父类和子类具有相同的非静态方法(就是子类重写父类方法),多态下访问的是子类重写后的成员方法

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘程云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值