【面向对象三大特征-Java基础】

Java面向对象三大特征

  • Java面向对象体现在哪些方面?
  • Java面向对象体现在:封装,继承,多态

1. 封装

  • 封装是指把一个对象的状态信息(也就是属性)隐藏在对象内部,不允许外部对象直接访问对象的内部信息。但是可以提供一些可以被外界访问的方法来操作属性。就好像我们看不到挂在墙上的空调的内部的零件信息(也就是属性),但是可以通过遥控器(方法)来控制空调。
  • 举个例子,新建一个Animal类,有两个私有属性name、age,使用private进行修饰的属性为私有属性,使用public修饰的方法或属性则为公有的,外部类可以直接调用;如果其他类需要访问Animal类中的两个私有属性,是不能直接访问的,需要Animal类提供一些方法来访问这些私有属性,比如getName(), getAge(), setName(), setAge()方法。 Animal animal = new Animal();创建一个对象, animal.setName(“小猫”);调用setName()方法来设置属性name的值,而不能直接调用animal.name = “小猫”.

public class Animal {
    /**
     * 私有化属性 name
     */
    private String name;

    /**
     * 私有化属性 age
     */
    private Integer age;

    /**
     * 获取name的方法
     *
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置name的方法
     *
     * @param name name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取age的方法
     *
     * @return age
     */
    public Integer getAge() {
        return age;
    }

    /**
     * 设置age的方法
     *
     * @param age age
     */
    public void setAge(Integer age) {
        this.age = age;
    }
}
public class TestMain {
  public static void main(String[] args) {
    Animal animal = new Animal();
    animal.setName("小猫");
    animal.setAge(2);
    System.out.println("animal name: " + animal.getName() + ", age: " + animal.getAge());
  }
}

2. 继承

  • 不同类型的对象,相互之间经常有一定数量的共同点。同时,每一个对象还定义了额外的特性使得他们与众不同,将共同的特点抽取出来作为父类。
  • 例如小狗爱吃骨头并且喜欢玩,小猫爱吃鱼并且喜欢玩;它们都有共同的特点吃和玩。继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。通过使用继承,可以快速地创建新的类,可以提高代码的重用,程序的可维护性,节省大量创建新类的时间,提高我们的开发效率。

PS:

  1. 子类拥有父类对象所有的属性和方法(包括私有属性和私有方法),但是父类中的私有属性和方法子类是无法访问,只是拥有。
  2. 子类可以拥有自己属性和方法,即子类可以对父类进行扩展。
  3. 子类可以用自己的方式实现父类的方法。
  4. 父类对象只能执行那些在父类中声明、被子类覆盖了的子类方法,如toString(),不能执行子类增加的成员方法。
  • 父类Animal ,子类Cat、Dog,Cat、Dog都继承Animal,

public class Animal {
    /**
     * 私有化属性 name
     */
    private String name;

    /**
     * 私有化属性 age
     */
    private Integer age;

    /**
     * 私有化属性,不提供对外方法
    */
    private String type; 
    public Animal() {
    }

    public Animal(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public void eat() {
        System.out.println("动物需要吃东西");
    }

    public void play() {
        System.out.println("动物喜欢玩");
    }

    /**
     * 私有方法
     */
    private void out() {
        System.out.println("动物out方法为私有方法");
    }
    /**
     * 获取name的方法
     *
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置name的方法
     *
     * @param name name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取age的方法
     *
     * @return age
     */
    public Integer getAge() {
        return age;
    }

    /**
     * 设置age的方法
     *
     * @param age age
     */
    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Animal{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
  • Cat类继承Animal类,重写父类的eat()方法,拥有自己的属性color
public class Cat extends Animal {
    private String color;

    public Cat(String name, Integer age, String color) {
        super(name, age);
        this.color = color;
    }

    @Override
    public void eat() {
        System.out.println("小猫喜欢吃鱼");
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    @Override
    public String toString() {
        return super.toString() + "Cat{" +
                "color='" + color + '\'' +
                '}';
    }
}

  • Dog类继承Animal类,重写父类的eat()方法,拥有自己的属性action

public class Dog extends Animal {
    private String action;

    public Dog(String name, Integer age, String action) {
        super(name, age);
        this.action = action;
    }

    @Override
    public void eat() {
        System.out.println("小狗喜欢吃骨头");
    }

    public String getAction() {
        return action;
    }

    public void setAction(String action) {
        this.action = action;
    }

    @Override
    public String toString() {
        return super.toString() + "Dog{" +
                "action='" + action + '\'' +
                '}';
    }
}
  • 测试类TestMain
public class TestMain {
    public static void main(String[] args) {
        Animal cat = new Cat("小猫",2,"白色");
        // 子类重写了父类的方法,执行子类的方法
        cat.eat();
        // 子类没有覆盖父类的方法,执行父类的方法
        cat.play();
        System.out.println(cat.toString());

        Animal dog = new Dog("小狗",3,"看家");
        // 子类重写了父类的方法,执行子类的方法
        dog.eat();
        // 子类没有覆盖父类的方法,执行父类的方法
        dog.play();
        System.out.println(dog.toString());
    }
}

测试结果:子类重写了父类的eat()方法,通过对象引用调用,会先执行子类方法;子类没有重写play()方法,通过对象引用调用,会先执行父类方法;父类的私有属性type,私有方法out() ,子类只能拥有,但是不能重写,也不能调用;子类独有的属性color、action,父类也不能调用。
在这里插入图片描述

3. 多态

多态,顾名思义,表示一个对象具有多种的状态。具体表现为父类的引用指向子类的实例。

  • 多态的特点:
  1. 对象类型和引用类型之间具有继承(类)/实现(接口)的关系;
  2. 对象类型不可变,引用类型可变;方法具有多态性,属性不具有多态性;
  3. 引用类型变量发出的方法调用的到底是哪个类中的方法,必须在程序运行期间才能确定;
  4. 多态不能调用“只在子类存在但在父类不存在”的方法;
  5. 如果子类重写了父类的方法,真正执行的是子类覆盖的方法,如果子类没有覆盖父类的方法,执行的是父类的方法。
  • 根据何时确定执行多态方法中的哪一个,多态分为两种情况:编译时多态和运行时多态

  • 如果在编译时能够确定执行多态方法中的哪一个,称为编译时多态,否则称为运行时多态。

  • 编译时多态:方法重载都是编译时多态。根据实际参数的数据类型、参数个数和参数次序,Java在编译时能够确定执行重载方法中的哪一个

  • 运行时多态: 方法覆盖表现出两种多态性,当对象引用本类实例时,为编译时多态,否则为运行时多态。例如,以下声明cat、dog引用本类实例,调用toString()方法是编译时多态。

  • 多态存在的三个必要条件
    一、要有继承;
    二、要有重写;
    三、父类引用指向子类对象。
    多态引用类型有两种方式:
    a. 编译时多态:方法的重载;
    b. 运行时多态:方法的重写;
    方法重写:
    在重写方法时,需要遵循以下的规则:
    (一) 父类方法的参数列表必须完全与被子类重写的方法的参数列表相同,否则不能称其为重写而是重载。
    (二) 父类的返回类型必须与被子类重写的方法返回类型相同,否则不能称其为重写而是重载。
    (三) Java中规定,被子类重写的方法不能拥有比父类方法更加严格的访问权限。
    (四) 由于父类的访问权限修饰符的限制一定要大于被子类重写方法的访问权限修饰符,而private权限最小。所以如果某一个方法在父类中的访问权限是private,那么就不能在子类中对其进行重写。
    在继承过程中如果父类当中的方法抛出异常,那么在子类中重写父类的该方法时,也要抛出异常,而且抛出的异常不能多于父类中抛出的异常(可以等于父类中抛出的异常)。
    方法重载:
    方法重载是指在一个类中,多个方法的方法名相同,但是参数列表不同。参数列表不同指的是参数个数、参数类型或者参数的顺序不同。
    方法重载规则:
    1)被重载的方法必须改变参数列表;
    2)被重载的方法可以改变返回类型;
    3)被重载的方法可以改变访问修饰符;
    4)被重载的方法可以声明新的或更广的检查异常;
    5)方法能够在同一个类中或者在一个子类中被重载。

  • 方法的重载代码实现:

public class Calculation {
    /**
     * 两个数相加
     *
     * @param num1 num1
     * @param num2 num2
     * @return sum
     */
    public double sum(double num1, double num2) {
        return num1 + num2;
    }

    /**
     * 三个数相加
     *
     * @param num1 num1
     * @param num2 num2
     * @param num3 num3
     * @return sum
     */
    public double sum(double num1, double num2, double num3) {
        return num1 + num2 + num3;
    }

    /**
     * 四个数相加
     *
     * @param num1 num1
     * @param num2 num2
     * @param num3 num3
     * @param num4 num4
     * @return sum
     */
    public double sum(double num1, double num2, double num3, double num4) {
        return num1 + num2 + num3 + num4;
    }
}
public class TestMain {
    public static void main(String[] args) {
        Calculation calculation = new Calculation();
        double two = calculation.sum(4, 5);
        System.out.println("两个数之和: " + two);
        double three = calculation.sum(4, 5, 6);
        System.out.println("三个数之和: " + three);
        double four = calculation.sum(4, 5, 6, 9);
        System.out.println("四个数之和: " + four);
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值