Java学习day10-封装和继承

封装和继承

今日目标:

封装
继承

1.封装

1.为什么要封装:
隐蔽性 安全性

1.类有成员属性和方法两个部分组成,二者都可以供其它类去调用。方法作为一个功能的实现,被调用时不会产生什么问题,属性却不一样,它是属于类和对象的,容易被“非法篡改”。

例如:定义一个类people,有姓名和财产等属性,默认值是:张三和12000.有show方法,输出姓名和财产。定义一个测试类,修改张三的money为-10000;

2.此案例可以看出类和对象的属性毫无隐蔽性可言,可以被随意修改,这样设计出的程序会有很大的安全性问题。
3.为了解决这个问题,java开发者提出了封装的思想。将类的成员属性的访问修饰符规定为私有(private),这样该属性在其它类就不能调用,更不可能被修改。这相当于闭关锁国政策,所以又面临一个问题:连成员属性的正常赋值也不可能在其它类中实现。因此设计者们再次提出了一个方案:成员属性可以间接地在其它类中被访问,也就是中间要设置一道检查和过滤的关卡,这道关卡就是get和set方法,它们被称为getter和setter.
下面我们对刚才的案例进行改进。

实现封装总结:
1.属性访问修饰符定义为私有:private
2.对外提供get和set方法。
Java学习day10-封装和继承
Java学习day10-封装和继承
Java学习day10-封装和继承

package com.Test1;

public class TestPerson {
    public static void main(String[] args) {
        Person p=new Person();
        p.setMoney(12000);
        p.setName("张三");
        p.setSex('女');
        System.out.println(p.getSex());//通过get取值
        p.show();
    }
}
package com.Test1;

public class Person {//封装
    private String name;
    private char sex;
    private double money;

    public void setSex(char sex){
        if (sex == '男'||sex=='女') {
            this.sex=sex;
        }else {
            this.sex='男';
        }
    }
    public char getSex(){
        return sex;
    }

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

    public void setMoney(double money){
        if (money>=0){
            this.money=money;
        }else {
            this.money=0;
        }
    }
    public double getMoney(){
       return money;
    }

    public void show(){
        System.out.println(name+"性别为:"+sex+" 财产为:"+money);
    }

}

Java学习day10-封装和继承
封装快捷键:alt+Insert(右键选择Generate)
然后选择Getter and Setter

Java学习day10-封装和继承
点击即可
Java学习day10-封装和继承

2.包结构

在开发大型项目时,会有很多功能模块的具体划分,这是需要建立很多的类,将同一层级的类放在一个包中,可使程序的层级结构清晰,提高辨识度。
类似于在资源管理器中新建一个文件夹,有规律的存放和管理资源文件。
Java学习day10-封装和继承

导包:导入自己的包和系统包
java.lang包是java语言的核心,它提供了java中的基础类。(java.lang这个包属于系统包,该包中的类不用导入,例如System,String)

3.访问修饰符

下图中:受保护的情况(protected) :子类必须在同一个包中。
Java学习day10-封装和继承

1.类的访问修饰符:
Public:对外公开
默认:所在包有效,包以外不能访问 --体现在构造方法上

2.成员访问修饰符(成员属性和成员方法)
Public:对外公开
Protected:受保护的,同一个包的子类可以访问。
默认:同一个包中可以访问
Private:只在当前类有效

4.static和this关键字

Static修饰的,属于类范围的,this代表当前对象。
Static修饰成员属性和方法和代码块
Java学习day10-封装和继承
Java学习day10-封装和继承

Java学习day10-封装和继承
Java学习day10-封装和继承

5.继承

1.引语:
如何理解继承,我猜大家首先想到的可能是继承千万家产,走上人生巅峰。梦想是美好的,java里面却不是这样的。
2.概念:
大千世界可以分为很多的类,有大范围的类,例如:动物和人,有小范围的类,例如:老虎,狮子,大象,老师,医生。
那这些类之间有什么关系呢?–包含
这种关系如何表示呢?–继承

总结:继承研究的是两个类之间的范围包含关系,用关键字extends表示。

3.使用:

  1. 在多个子类中抽取出相同的属性和方法,形成父类的属性和方法
  2. 在各个子类中继承这些属性和方法的使用权限。

Java中的继承需要从两个方面去理解:
1.在多个子类中抽取出相同的属性和方法,形成父类的属性和方法
案例:
大象和狮子 都具有属性:名称,体重,战斗力;方法:捕食。
可以提取这些相同的属性,形成一个父类 动物类。
创建测试类,在测试类中创建狮子对象,继承父类的属性和方法

Java学习day10-封装和继承
Java学习day10-封装和继承
优点:
抽取出共有的重复的代码,使用继承,提高代码的复用性

Java学习day10-封装和继承
Java学习day10-封装和继承
Java学习day10-封装和继承

Java学习day10-封装和继承
Java学习day10-封装和继承

2.对父类成员的继承使用(包含成员属性和成员方法)

抽取出共有的重复的代码,使用继承,提高代码的复用性,

让类与类之间产生关系:extends

继承是两个类之间产生关联关系的唯一的方式
4.继承语法细节:

1.子类构造方法会默认调用父类无参构造方法。
即:在创建子类对象时,也会随即创建父类对象。

为多态提供了前提

2.Java中支持单继承:一个子类只能有一个直接父类

Java中不支持多继承
3.任何一个类,都默认继承Object类,Object类是所有类的父类。

6.this和super的区别

this:
1.本类成员方法中,访问本类成员变量,访问本类另一个成员方法
2.本类构造方法中,访问本类另一个构造方法

Super:
1.在子类成员方法中,访问父类成员变量和成员方法
2.在子类构造方法中,访问父类构造方法

本类的成员变量和局部变量重名,用this区分,
本类的成员变量和父类的变量重名,用super区分
Java学习day10-封装和继承

重写(覆盖)和重载
重载:同一个类中,方法名相同方法参数不同,典型应用:无参构造和有参构造

重写:子类和父类同名的方法。
子类方法和父类方法同名,子类方法会覆盖父类方法,称为重写(覆盖),前提,子类方法访问权限必须大于或等于父类方法的访问权限
什么时候会用到覆盖?
案例:手机需要扩展新功能,反复修改代码会带来毁灭性的灾难。此时采用继承是不错的选择
Java学习day10-封装和继承

Final
修饰的变量称为常量,值不能被修改
修饰的方法不能被重写,保证安全性和稳定性
修饰的类不能被继承,避免功能被覆盖。

要想让一个类不被其它类继承:
1.用final修饰
2.构造方法私有化
Java学习day10-封装和继承

作业:
1.需求说明
使用封装实现电子宠物系统的企鹅类正确输入健康值和亲密度
保证健康值的有效性(0-100),否则取默认值60
保证亲密度的有效性(0-100),否则取默认值60
Java学习day10-封装和继承

package com.homework.one;

import java.util.Scanner;

public class TestPets {
    static Scanner sc=new Scanner(System.in);
    public static void main(String[] args) {
        Pets p1 = new Pets();
        System.out.println("欢迎您来到宠物店!");
        System.out.print("请输入要领养的宠物名字:");
        String a=sc.next();
        p1.setName(a);

        System.out.print("请选择要领养的宠物类型:(1、狗狗2、企鹅)");
        String b=sc.next();
        p1.setType(b);

        System.out.print("请选择"+p1.getType()+"的性别:(1.Q仔 2.Q妹)");
        String c=sc.next();
        p1.setSex(c);

        System.out.print("请输入"+p1.getType()+"的健康值(1~100之间)");
        int d=sc.nextInt();
        p1.setHealthy(d);

        System.out.println("宠物的自白:");
        System.out.println("我的名字叫"+p1.getName()+",健康值是"+p1.getHealthy()
        +",和主人的亲密度是100,我的性别是"+p1.getSex());
    }
}
package com.homework.one;

public class Pets {
    private String name;
    private String type;
    private String sex;
    private int healthy;

    public String getName() {
        return name;
    }

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

    public String getType() {
        return type;
    }

    public void setType(String type) {//类型
        if (type.equals("1")){
            this.type = "狗狗";
        }else {
            this.type = "企鹅";
        }

    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        if (sex.equals("1")){
            this.sex = "Q仔";
        }else {
            this.sex = "Q妹";
        }
    }

    public int getHealthy() {
        return healthy;
    }

    public void setHealthy(int healthy) {
        if (healthy>=0&&healthy<=100){
            this.healthy = healthy;
        }else {
            System.out.println("健康值应该在1-100之间,默认为60");
            this.healthy = 60;
        }

    }
}

Java学习day10-封装和继承

2.需求说明
模拟实现选民投票过程:一群选民进行投票,每个选民只允许投一次票,并且当投票总数达到100时,就停止投票

package com.homework.two;

public class Vote {
    public static void main(String[] args) {
        System.out.println("请投票");
        int i=1;
        do {
            System.out.println("第"+i+"个村民投票");
            i++;
        }while (i<=100);
    }
}

3.需求说明
使用继承优化电子宠物系统,抽取父类,创建子类,在子类中使用super调用父类构造方法。(选做)
4.编写一个类Student1,代表学员,要求如下:
具有属性:姓名和年龄,其中年龄不能小于16岁,否则输出错误信息
具有方法:自我介绍,负责输出该学员的姓名和年龄。
编写测试类Student1Test进行测试,看是否符合需求。
在学员类的setAge()方法中验证年龄大小。
在测试类中分别测试学员年龄小于16岁、大于16岁时的输出结果

package com.homework.four;

public class Student1 {
    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<16){
            System.out.println("年龄不能小于16岁,默认为16岁");
            this.age=16;
        }else {
            this.age = age;
        }
    }
    public  void introduce(){
        System.out.println("姓名:"+name+" 年龄:"+age);
    }
}
package com.homework.four;

import java.util.Scanner;

public class Student1Test {
    public static void main(String[] args) {
        Student1 s1 = new Student1();
        Scanner sc=new Scanner(System.in);
        System.out.println("请输入学员的年龄:");
        int a=sc.nextInt();
        s1.setAge(a);
        System.out.println("请输入学员姓名:");
        String b=sc.next();
        s1.setName(b);
        s1.introduce();

    }
}

Java学习day10-封装和继承
Java学习day10-封装和继承

5.编写一个类Student2,代表学员,要求如下:
具有属性:姓名、年龄、性别和专业
具有方法:自我介绍,负责输出该学员的姓名、年龄、性别和专业
具有两个带参构造方法:在第一个构造方法中,设置学员的性别为男,专业为java,其余属性的值由参数给定;在第二个构造方法中,所有属性的值都由参数给定。
编写测试类Student2Test进行测试,分别以两种方式完成对两个Student2对象的初始化工作,并分别调用他们的自我介绍方法,看输出结果是否正确。
在学员类中定义如下两个构造方法完成初始化工作:
Public Student2(Stiring name,int age){}
Public Stduent2(String name,int age,String sex,String subject){}

package com.homework.five;

public class Student2 {
    private String name;
    private int age;
    private String sex;
    private String major;

    public void introduce(){//介绍
        System.out.println("姓名:"+name+"\n年龄:"+age+"\n性别:"+sex+"\n专业:"+major);

    }

    public Student2(String name, int age, String sex, String major) {
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.major = major;
    }

    public Student2(String sex, String major) {
        this.sex = sex;
        this.major = major;
    }

    public Student2() {
    }

    public String getSex() {
        return sex;
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getMajor() {
        return major;
    }

    public void setMajor(String major) {
        this.major = major;
    }
}
package com.homework.five;

public class Student2Test {
    public static void main(String[] args) {
        Student2 s2=new Student2("张三",20,"男","java");
        s2.introduce();
        System.out.println("---------------");
        Student2 s1 = new Student2("男","java");
        s1.setAge(20);
        s1.setName("张三");
        s1.introduce();

    }
}

Java学习day10-封装和继承

6.设计Bird、Fish类,都继承父类Animal的属性和方法info(),并输出他们的信息。参考运行结果如下所示:
我是一只红色的鸟! Color
今年4岁了! age

我是一只5斤重的鱼! weight
今年2岁了! age

提示:
定义父类Animal,具有age属性、info()方法
定义Bird类,具有本身的特有属性color
定义Fish类,具有本身的特有属性weight。

7.兜兜家养了两只家禽:一只鸡和一只鸭。请用面向对象思想的封装、继承的特性进行描述,参考运行结果如下所示:
我叫喔喔,是一只芦花鸡!Name type
我喜欢吃虫子! hobby
我会打鸣!crow

我叫嘎嘎,是一只斑嘴鸭!Name type
我喜欢吃小鱼虾!hobby
我会游泳! swim

提示:
分析上图的运行结果,通过名词找出类、属性,通过动词找出方法
将公有的属性和方法抽象到父类中
让子类继承父类,并实现子类特有的属性和方法

作业二
知识测试题

1.按需求实现功能(构造方法、封装、继承、重写)
(1)编写地址类Address,包含属性:
①城市
②所属区
(2)编写医生类Doctor,包含属性:
①名字
②所属科室
③年龄
④地址:地址类型
⑤性别
⑥print方法打印个人信息
(3)编写老师类Teacher,包含属性
①名字
②年龄
③地址:地址类型
④性别
⑤所授学科
⑥print方法打印个人信息
(4)所有属性封装
(5)根据分析编写一个父类Person和子类产生继承关系
(6)对所有人年龄加上范围控制,不能小于1,不能大于130
(7)重写优化print方法
(8)每个类编写全参和无参构造方法
(9)每个类分别重写toString()方法打印属性&属性值
(10)main方法通过构造方法赋值并且打印对象输出员工信息
(11)注意命名规范,所有命名不得使用拼音,驼峰该驼的驼起来,代码格式,缩进,对齐,每个类单独写一个java文件

上一篇:day10【排序算法、异常】


下一篇:Linux实操篇-day10-网络配置