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

面向对象的三大特性(封装、继承、多态)

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

面向对象的三大特性(封装、继承、多态)

封装

使用private修饰符对属性进行修饰,限制属性的访问权限,只有类内部能够访问这样的属性,其他的类通过对象、属性的方式是无法访问的,从而对对象的状态(数据)进行保护,外部类要访问的话需要通过调用get/set的方法,保证属性统一访问

  • 学生类student

有一些属性,都是用private修饰

提供get、set方法访问属性,在set时候可以限制赋值的内容,在get时可以返回指定格式的数据,转换和限制逻辑封装在类中

public class Student {
    //private 私有修饰符
    private String name;
    private  int sex;
    private int age;
​
    public String getName() {
        return name;
    }
​
    public void setName(String name) {
        this.name = name;
    }
​
    public String getSex() {
        //返回字符串
        String result = sex == 1? "男" : "女";
        return result;
    }
​
    public void setSex(int sex) {
        //限制性别的赋值,不允许随便赋值
        if(sex < 0 || sex > 1){
            throw new RuntimeException("性别只能为0或1");
        }
        this.sex = sex;
    }
​
    public int getAge() {
        return age;
    }
​
    public void setAge(int age) {
        this.age = age;
    }
}
​
  • 使用学生类StudentTest

使用学生类时不能直接访问属性,必须通过get、set方法

如果给属性(成员变量)赋值不符合要求就报异常

用get方法读取属性,会读取到学生类转换之后的内容

public class StudentTest {
    public static void main(String[] args) {
        Student student = new Student();
//        student.name = "小丽";//私有成员变量,不能直接用对象.属性访问
        student.setAge(22);
        student.setSex(1);//对性别赋值,赋值的时候set对其限定输入
        System.out.println(student.getSex());//打印赋的性别,返回的时候get指定返回格式
       
    }
}
访问修饰符

控制访问权限的关键字称为访问修饰符,有private、default、protacted、public(类前面只能用public)

访问修饰符可以用在成员变量以及方法前面。局部变量不需要访问修饰符

同类同一个包子类其他类
private√×××
default(不写修饰符)√√××
protected√√√×
public√√√√

注(自己理解):

private:相当于自己,我的私人物品我自己(同类:我自己)能用,其他人(同一个包、子类、其他类:不是我的)所有都不能用

default:相当于恋爱的情侣,两人共有(同类、同一个包:吃的、穿的)的一些东西能用,外人(子类、其他类:)不能对我们的恋情指手画脚

protected:相当于一家人,家(同类、同一个包、子类)里面的物品可以直接用,家(其他类)以外的不能用

public:公共的,没有限制,想用就用(同类、同一个包、子类、其他类)

继承

A类可以通过extends关键字继承B类,继承之后A类可以有一些B类中的属性或方法,实现代码重复利用

语法:

【修饰符】class 子类 extends 父类{

}

子类也叫派生类,或者叫衍生类,subClass

父类也叫基类,超类,superClass

继承的特点
  1. 继承只能单继承,只能有一个父类;一个父类可以有多个子类

  2. 继承可以多重继承:A继承B,B继承C

  3. Object是所有类的父类(所有的类都是继承至Object)

  4. 子类可以重写(覆盖)父类的方法

  5. 在创建子类的时候,会先去执行父类的构造方法

代码案例

父类 Shap定义了一个成员变量name,一个方法area()

子类Retangle继承了父类Shap,Retangle自动有name属性和area()方法

子类中定义自己的属性,也可以写自己的方法,还可以重写父类继承来的方法

  • 父类Shap

public class Shap {
    public String name;

    public void area(){
        System.out.println("显示图形的面积");
    }
}
  • 子类Retangle

//extends 关键字
public class Retangle extends Shap{
    private float width;//定义私有属性 矩形的宽度
    private float height;//矩形的高   类的属性通过构造方法赋值

    public Retangle(float width, float height) {
        this();//调用无参的构造方法;  在构造方法中调用其他构造方法代码写在第一行
        this.width = width;
        this.height = height;
    }

    public Retangle() {
        this.name = "矩形";  //对name赋值
    }

    @Override  //注解:这是重写或者覆盖父类的方法
    public void area() {  //面积
        float area = width * height;
        System.out.println(area); //输出面积area
    }
}
  • 测试代码

public class RetandleTest {
    public static void main(String[] args) {
        Retangle retangle = new Retangle(5,4);//对高和宽赋值
        retangle.area();//使用Retangle的area方法   
        System.out.println(retangle.name);//输出name

    }
}

重写和重载 重写override(覆盖)

当子类继承父类的时候,对父类的方法代码重写写过,就叫重写

重写的特性:

  • 方法名、参数列表(个数、类型、顺序),返回类型完全一致

  • 访问权限(修饰符)不能比父类更小(跟父类的访问权限一样或更大)

  • 如果要抛出异常,不能够比父类的异常更大

重载overload

在一个类中(不一定要继承),如果有多个方法名相同,参数列表不同(个数、类型、顺序),这些同名的方法称为重载

重载的特性:

  • 方法名相同

  • 参数列表不同(个数、类型、顺序)

public class Rect {
    
    //计算正方形面积
    public void area(int width){
        System.out.println(width * width);
    }
    
    //方法名相同,参数不同
    
    //计算长方形面积
    public void area(int width , int height){
        System.out.println(width * height);
    }
}

this和super关键字

这两个关键字都可以指代对象或构造方法

当成对象用的

public Shap() {
        this.name = "形状"; //在构造方法里this代表当前对象
        System.out.println(this.name);
    }

public void setAge(int age) {
        this.age = age;  //age是局部变量,加this.age的是成员变量
    }//this用在set方法里面,代表当前对象

public void parentArea(){
        super.area();//在子类中要去访问父类的方法,用super.方法()
    }
当成构造
方法使用
  • 在构造方法中调用构造方法,用this代替构造方法名。

  • 在构造方法中调用构造方法,调用语句只能放在第一行

  • 子类要调用父类的构造方法,用super()

  • 如果子类的构造方法没有调用父类的构造方法,默认会调用父类的无参的构造方法

  • 如果父类没有无参的构造方法,在子类的构造方法中必须要去(super)调用父类的有参的构造方法

public class Parent {
    private int age;
    private String name;
    private int sex;

    public Parent() {
        System.out.println("无参");
    }

    public Parent(String name, int sex) {
        this.name = name;
        this.sex = sex;
        System.out.println("两个参数");
    }

    public Parent(int age, String name, int sex) {
        this(name,sex);//调用两个参数的构造方法,用在第一行
        this.age = age;
        System.out.println("三个参数");
    }

    public static void main(String[] args) {
        new Parent(22,"张三",1);
    }
}


public class Son extends Parent{
    private int age;
    private String name;
    private int sex;

    public Son(){
        super();//执行父类的构造方法,不写也会自动调用
        System.out.println("son 无参");
    }

    public Son(String name, int sex) {
        this.name = name;
        this.sex = sex;
        System.out.println("son 两个参数");
    }

    public Son(int age, String name, int sex) {
        super(age,name,sex);
        this.age = age;
        this.name = name;
        this.sex = sex;
        System.out.println("son 三个参数");
    }

    public static void main(String[] args) {
//        Son son = new Son();
        new Son(22,"小王",0);
    }
}
多态

一个类在编译的时候和运行时同一个方法呈现出不同的状态。

比如:动物类有一个发出叫声的方法,它的子类有猫类,猫的叫声是“喵喵”;还有一个子类是狗类,狗的叫声“汪汪”。 现在有一个动物类的对象,调用发出叫声的方法,有可能叫:喵喵,也可能叫:汪汪

形成多态的条件:

  1. 有继承关系,有多个子类,子类重写父类的方法

  2. 父类类型定义的变量,用子类的实例给它赋值

多态的用处:

统一管理,无限适配或扩展

  • Animal.java

public class Animal {
​
    public void shout(){
        System.out.println("动物在叫");
    }
}
  • Cat

public class Cat extends Animal{
    @Override
    public void shout() {
        System.out.println("喵喵喵");
//        super.shout();
    }
}
  • Dog

public class Dog extends Animal{
    @Override  //重写
    public void shout() {
        System.out.println("汪汪");

    }
}
  • 测试代码

public class AnimalTest {
    public static void main(String[] args) {
        Animal animal1 = new Animal();
        animal1.shout();//动物类的叫声
        Cat cat = new Cat();
        cat.shout();//喵叫
        Dog dog = new Dog();
        dog.shout();

        Animal animalCat = cat;//“喵喵喵” 赋值给 “动物在叫”
        animalCat.shout();//喵叫“喵喵喵”

        Animal animalDog = dog;
        animalDog.shout();
    }
}

向上造型

父类 变量 = new 子类();

父类定义的变量,用子类的实例对象赋值

注意:向上造型的时候,不能调用到子类中自己添加的方法

	Animal animalCat = cat;//“喵喵喵” 赋值给 “动物在叫”
        animalCat.shout();//喵叫“喵喵喵”

        Animal animalDog = dog;
        animalDog.shout();

向下造型

子类 变量 = (子类)父类的对象;

用父类的对象给子类的变量赋值,向下造型必须用强制类型转换

向下造型分几种情况:

  1. 直接new一个父类对象赋给子类变量,运行会报异常

  2. 父类对象是通过子类的对象向上造型上去的实例,这种对象可以向下造型,要强转,子类的所有方法都可以访问

  3. 跟2一样的做法,但是换了子类,如猫的子类的对象,向下造型成狗,不允许,运行时报异常

        //向下造型
        //1.直接用父类创建的对象赋给子类变量,会报异常
//        Cat cat = (Cat) new Animal();

        //2.把通过向上造型得到的父类对象赋给子类对象,可以调用继承至父类的方法,也可以子类自己的方法
        Animal animal1 = new Cat();
        System.out.println("*******向下*******");
        Cat cat1 = (Cat) animal1;
        cat1.shout();
        cat1.eat();

		//3.造型是子类发生了变化
        System.out.println("********");
        Animal animal2 = new Dog();
        Cat cat2 = (Cat) animal2;//会报异常
        cat2.shout();
        cat2.eat();

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

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

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