[java小知识]详解Java三大特性 封装、继承和多态


在这里插入图片描述

Java三大特性 😍

1.封装1️⃣

🚗 1.1 为什么要封装?

先看一段简单的代码

class Person{
    String name;
    int age;
    public void speak(){
        System.out.println("姓名"+name+"年龄"+age);
    }
}
public class test{
    public static void main(String[] args){
        Person p=new Person();
        p.name="三连";
        p.age=1200;
        p.speak();
    }
} 

可以看出代码在运行上没有什么问题,但是在现实生活中明显是不合理的。没有人会有1200岁吧。因此在设计一个Java类时就要对成员变量的访问做一些限制。不允许外界随意访问。这就需要实现类的封装

🎠1.2 那如何实现封装?

 类的封装是指,将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象的内部信息,而是通过该类多提供的方法来实现对内部信息的操作和访问。

 具体的实现方式就是将类中的属性私有化,也就是使用private进行修饰,然后这个属性就只能在类内部进行访问。如果外界想要访问私有属性,就需要类内部提供一些public修饰的共有方法。也就是常用的setXxx()getXxx() 方法

在对上面的代码进行封装

class Person{
    private String name;
    private int age;

    public String getName(){
        return name;
    }
    public void setName(String name){
        this.name=name;
    }
    public int getAge(){
        return age;
    }
    public  void setAge(int age){
        if(age<=0||age>120){
            System.out.println("输入有误");
        }else{
            this.age=age;
        }
    }
    public void speak(){
        System.out.println("姓名"+name+"年龄"+age);
    }
}
 class test{
    public static void main(String[] args){
        Person p=new Person();
        p.setName("三连");
        p.setAge(1200);
        p.speak();
    }
}

可以看出我们把成员变量设置成了私有private,而且每个成员变量都设置了自己的set、get方法,可以在set方法里面对条件进行限制

运行结果为

在这里插入图片描述

可以看出年龄大于120,所以还是为初始值0

2.继承2️⃣

在这里插入图片描述

⛵️2.1 什么是继承?

  在Java中继承指的是在一个现有类的基础上去构建一个新的类,构建出来的新的类被称作子类,现有类被称作父类或者基类,子类会自动拥有父类所有可继承的属性和方法。在程序中需要使用关键字extends去生命一个类继承另一个类

class Aniamal{
    String name;
    void  shout(){
        System.out.println("动物基类");
    }
}
class Dog extends Aniamal{
    public void print(){
        System.out.println("名字是"+name);
    }
}
class test{
    public static void main(String[] args) {
        Dog dog=new Dog();
        dog.name="傻狗";
        dog.print();
        dog.shout();
    }
}

运行结果

在这里插入图片描述

  可以看出Dog类继承了Animal类,即使Dog类中没有声明name属性和shout方法,但是却能访问这两个成员。这说明。子类在继承父类时,会自动拥有父类的公共成员

🚀2.2继承需要注意的点
  • 在Java中类只支持单继承,不允许多重继承
  • 多个类可以继承同一个父类
  • 一个类的父类可以再去继承另外的父类,也就是可以多层继承。例如下面这种情况
class A{}
class B extends A{}
class C extends B{}
🚲2.3 重写父类方法

  在继承关系中,子类会自动继承父类中公共的方法,但有时在子类中需要对继承的方法进行一些修改,那又该怎么办呢?

可以重写父类中的方法。

👍需要注意的是,子类中重写的方法需要和父类中被重写的方法

  • 具有相同的方法名、参数列表、以及返回值类型
  • 子类重写父类方法时,不能使用比父类中被重写的方法更严格的访问权限。比如父类中的方法访问权限是public,子类重写该方法时访问权限就不能是private、protected
2.2.1关于default修饰符

相信就会有人问了,为什么defaule的权限也比public的权限小,而子类重写该方法时访问权限不应该不能是private、protecteddefault这三种吗?为什么你少写了一个❓

在这里插入图片描述
这里我也解释一下:

可以看出上面的图中,提示信息翻译过来就是Extension methods can only be used within an interface -> 扩展方法只能在接口中使用原来这个修饰符在修饰方法的时候,只能修饰接口中的方法,普通方法是不能使用的

2.2.2那这里在说一下访问修饰符
访问范围privatedefaultprotectedpublic
同一类中
同一包中
子类中
全局范围
🚠2.4 super关键字

  在子类重写父类的方法后,子类对象将无法直接访问父类被重写的方法。为了解决这个问题,在Java中专门提供了一个super关键字类访问父类的成员。例如访问父类的成员变量、成员方法和构造方法。使用起来也非常简单

super.成员变量
super.成员方法(参数,...)

  需要注意的是,通过super关键字调用父类构造方法的代码必须位于子类构造方法的第一行,并且只能出现一次,否则程序在编译期间就会报错

3.多态3️⃣

🚒3.1 什么是多态

  多态是指不同对象在调用同一个方法时多呈现出的多种不能行为。多态消除了类之间的耦合关系,大大提高了程序的可扩展性和可维护性。

  • 多态离不开类的继承、方法重写、父类引用指向子类对象这三点。

  由于一个父类可以有多个子类,各个子类都可以重写父类方法,并且多个不同的之类对象也可以指向同一个父类。这样程序只有在运行时才能知道具体代表的时哪个子类对象,这就体现了多态性

//定义抽象类
abstract class Animal{
    abstract void shout();
}
class Cat extends Animal{

    @Override
    void shout() {
        System.out.println("小猫");
    }
}
class Dog extends Animal{

    @Override
    void shout() {
        System.out.println("小狗");
    }
}
class test{
    public static void main(String[] args) {
        Animal a2=new Cat();
        Animal a1=new Dog();
        a2.shout();
        a1.shout();
    }
}

运行结果

在这里插入图片描述

上面的代码中我们分别定义了Cat、Dog类来是实现抽象类Animal。在测试类中分别创建了Cat、Dog两个类的对象同时指向一个父类对象,并调用shou()。程序在编译时自动识别具体的子类对象,从而选择性的调用对应的方法,这就是多态性的体现。

🚄 3.2对象类型转换
3.2.1向上转型
  • Animal a2=new Cat();
    Animal a1=new Dog();
    

    这两句牵扯到了类型转换,这样的类型转换成为向上转型

  • 向上转型是父类引用指向子类对象。所涉及的问题就是,只能访问子类从父类继承来的方法(子类和父类都有拥有的方法),而不能访问子类中自己定义的方法(只在子类中有的方法)。

    在编译时,会先检查调用的方法在父类中是否存在,如果不存在,会编译不通过。如果存在,在运行时会执行子类中的方法

    也就是编译看左边,运行看右边

3.2.2 向下转型

要想解决可以调用子类中自己独有的方法时,可以采用向下转型的方式

abstract class Animal{
    abstract void shout();
}
class Cat extends Animal{

    @Override
    void shout() {
        System.out.println("小猫");
    }
}
class Dog extends Animal{

    @Override
    void shout() {
        System.out.println("小狗");
    }
    public void show(){
        System.out.println("来吧小狗展示");
    }
}
class test{
    public static void main(String[] args) {
        Animal a1=new Dog();
        a1.shout();
        Dog dog=(Dog) a1;
        dog.show();
    }
}

运行结果在这里插入图片描述

上面的代码中Dog类中定义了一个show方法,要想调用的话,就可以强制转型。

3.2.3 instanceof关键字
class test{
    public static void main(String[] args) {
        Animal a1=new Dog();
        a1.shout();
        Dog dog=(Dog) a1;
        Cat cat=(Cat) a1;//注意这一句
        dog.show();
    }
}

注释的这一句在进行编译的时候不会报错。但是执行的时候会报异常在这里插入图片描述

  • 原因是创建的a1对象本身是一个Dog对象,在强制转换时,很显然时无法转换成Cat类型。

为了避免这种情况。可以使用instanceof关键字,它可以判断一个对象是否为为各类(或接口)的实例或者子类实例

那我们就可以这样改造代码

class test{
    public static void main(String[] args) {
        Animal a1=new Dog();
        a1.shout();
        Dog dog=(Dog) a1;
        if(a1 instanceof Cat){
            Cat cat=(Cat) a1;
        }else{
            System.out.println("不是Cat类型");
        }
        dog.show();
    }
}

运行结果在这里插入图片描述

可以看出使用这个关键字后就没有报出异常了。💯
在这里插入图片描述

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

圆○

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

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

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

打赏作者

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

抵扣说明:

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

余额充值