Java面向对象的三大特征-封装、继承、多态

一、封装

1、封装
(1)基本概念:实现隐藏细节,如果想要访问可使用对外提供的接口
(2)private关键字:访问权限修饰符,表示私有的,如果属性或者方法使用了private关键字修饰,那么他们只能在本类中进行访问,而在本类之外创建对象后不能直接访问该属性或者方法,如果想要在类的外部进行访问需要调用特定的方法接口进行访问。
(3)示例代码:

 public class privateTest {
    public static void main(String [] args){
        Cat cat = new Cat("花花" , 3);
        cat.getEat();
        cat.getName();
        cat.getAge();
    }
}
class Cat{
    private String name;
    private int age;
    public Cat(String name,int age){
        this.name = name;
this.age = age;
    }
    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
    public void setAge(int age){
        this.age = age;
    }
    public int getAge(){
        return age;
    }
    private void eat(){
        System.out.println("我是"+name+"我"+age+"岁了"+"我爱吃东西");
    }
    public void getEat(){
        eat();
    }
}

(4)封装的好处:
① 使代码模块化
② 可以隐藏重要信息
③ 代码重用
④ 插件化易于测试
⑤ 具有较好的安全性
(5)封装的缺点:会影响执行的效率

二、继承

(1)概念:继承就是从已有的类中派生出新的类,新的类能够拥有或者使用已有类的属性或者方法,并可以拓展出新的能力。
(2)被继承的类称为父类(超类),继承父类的称为子类(派生类)
(3)语法规则:class 子类名 extends 父类名 { }
(4)继承一个类只能继承非私有的数据(属性和方法)
(5)protected关键字:访问修饰权限,在父类中使用protected修饰的属性或者方法可以被子类所继承
(6)继承的限制:
① Java中类只能实现单继承,也就是一个类只能继承一个父类
② 在Java中允许有多重继承关系,即一个子类可以有一个父类,这个父类还可以有他自己的父类
③ 构造方法不能够继承
思考:为什么在创建子类对象的时候父类的构造方法也会被调用?
因为在Java中,子类要使用父类的数据,从而父类就需要通过构造方法来初始化数据。
注意:当创建子类对象时如果父类没有任何构造方法,那么这类就会调用父类的默认构造方法
(7)在实例化子类对象时,会首先调用父类的构造方法,如果父类中没有默认的构造方法,那么子类必须显示的通过super(……)来调用父类的带参构造方法,并且super语句只能在子类构造方法的第一句。
代码示例:

public class JichengTest {
    public static void main(String [] args){
        Dog dog = new Dog("大黄", 2, "公");
        dog.eat();
        //System.out.println(dog.name);  //在父类中name是私有的属性不能继承过来
        System.out.println(dog.getName());
        System.out.println(dog.age);
        //dog.drink(); //因为在父类中drink方法是私有的不能被继承所以编译时会报错
    }
}
class Animal {
    private String name;
    int age;
    public Animal(String name,int age){
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void getName(String name){
        this.name = name;
    }
    protected void eat(){
        System.out.println("我们都爱吃");
    }
    private void drink(){
        System.out.println("我们都要喝水");
    }
}
class Dog extends Animal{
    String sex;
    public Dog(String name , int age , String sex){
        super(name,age);  //显示的调用父类的构造方法
        this.sex = sex;
    }
}

(8)继承的好处:
① 减少了代码的冗余,提高了代码的复用性
② 提高了代码的维护性
③ 让类与类之间产生了关系,是多态的前提
(9)继承的缺点:只能实现单继承关系
(10)Overloading和Overring有什么区别?
Overloading:方法的重载,发生在同一个类,方法名相同,参数列表不同,与返回值无关
Overriding:方法的重写,发生在子父类中,方法名相同,参数列表相同,返回值相同,子类的访问修饰符要大于或者等于父类的访问修饰符,子类的异常声明必须小于或者等于父类的异常声明。如果方法被private 、static 、final修饰,那么此方法就不能被重写。

三、多态

(1)概念:对象在运行中的多种形态。
(2)继承关系图:
在这里插入图片描述
(3)语法:Chicken homeChicken = new HomeChicken(); 用父类引用指向子类对象(向上转型)
(4)instanceof关键字:instanceof适用于检查对象是否为指定的类型,通常用于再把父类引用强制转换为子类引用时,避免发生类型转换异常(ClassCastException)
(5)多态的使用(以投喂鸡食为例)

//先定义一个抽象的鸡类(父类)
abstract class Chicken{
    private String name;
    //构造器
    public Chicken(String name){
        this.name = name;
    }
    //get方法
    public String getName(){
        return name;
    }
    //抽象方法
    public abstract void eat();
}
//家鸡类(子类)
class HomeChicken extends Chicken{
    public HomeChicken(String name){
        super(name);
    }
    //重写eat方法
    @Override
    public void eat() {
        System.out.println("我是"+this.getName()+"我爱吃面");
    }
}
//野鸡类(子类)
class WildChicken extends Chicken{
    public WildChicken(String name){
        super(name);
    }
    //重写eat方法
    @Override
    public void eat() {
        System.out.println("我是"+this.getName()+"我爱吃虫子");
    }
    //定义一个特有的方法
    public void show(){
        System.out.println("我长得很黑,像煤球");
    }
}

测试方法一:

//测试--方法一 
public class DuotaiTest {
    public static void main(String [] args){
        Chicken homeChicken = new HomeChicken("家鸡");
        Chicken wildChicken = new WildChicken("野鸡");
        homeChicken.eat();
        wildChicken.eat();
    }
}

思考:通过方式一的测试,我们确实达到了对两只鸡进行投喂的目的,但是如果当鸡的数量变得很多的时候呢?如果我们还像方式一那样创建一个对象调用一次eat方法是不是就会显得很麻烦?那么此时我们就可以利用多态的特性,定义一个专门进行投喂的方法利用多态进行对象的参数传递,这样我们就可以优化我们的代码了。
测试方法二:

 //测试--方法二
public class TestTwo{
    public static void main(String [] args){
        getEat(new HomeChicken("家鸡"));
        getEat(new WildChicken("野鸡"));
    }
    public static void getEat(Chicken chicken){
        chicken.eat();
    }
}

那么问题来了:
在这里插入图片描述
我们会发现wildChicken.show()会报错,而报的使类型转换异常(ClassCastEception)这里是为什么呢?
首先我们要记住一句话:“编译看左边,运行看右边”,重要的事情说三遍:“编译看左边,运行看右边”,“编译看左边,运行看右边”,“编译看左边,运行看右边”;在创建对象的时候Chicken wildChicken = new WildChicken(“野鸡”);“=”的左边,此时Chicken就是wildChicken的编译类型,“=”的右边就是wildChicken的运行类型(WildChicken),因为show方法是WildChicken(子类)中的特有的方法,所以编译不通过,运行时又是WildChicken型,因此会报类型转换异常(ClassCastException),当我们需要调用子类中的方法时,我们就可以使用向下转型来解决,此刻instanceof关键字就起到了至关重要的作用了。

测试方法三

//测试--方法三
public class TestThree{
    public static void main(String [] args){
        Chicken homeChicken = new HomeChicken("家鸡");
        Chicken wildChicken = new WildChicken("野鸡");
        getEat(homeChicken);
        getEat(wildChicken);
    }
    public static void getEat(Chicken chicken){
        if (chicken instanceof WildChicken){
            //向下转型
            WildChicken wildChicken_one = (WildChicken) chicken;
            wildChicken_one.show();
        }
        chicken.eat();
    }
}

(6)小结:
① 多态就是对象在运行过程中的多种状态
② 向上转型:父类的引用指向子类对象
向下转型(强制转换):将父类的引用类型转为子类的引用类型
③ 多态的好处:提高了代码的扩展性和可维护性
④ 多态的前提:要有继承关系或者实现关系(接口)
要有方法的重写
要有父类或者父接口指向子类对象

四、说在最后

如果喜欢就点个免费的赞吧,这也是对我的最大鼓励!若有错误欢迎大家指出,我们相互学习共同成长!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值