Java学习day10-封装和继承

今日目标:

封装
继承

1.封装

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

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

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

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

实现封装总结:
1.属性访问修饰符定义为私有:private
2.对外提供get和set方法。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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);
    }

}

在这里插入图片描述
封装快捷键:alt+Insert(右键选择Generate)
然后选择Getter and Setter

在这里插入图片描述
点击即可
在这里插入图片描述

2.包结构

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

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

3.访问修饰符

下图中:受保护的情况(protected) :子类必须在同一个包中。
在这里插入图片描述

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

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

4.static和this关键字

Static修饰的,属于类范围的,this代表当前对象。
Static修饰成员属性和方法和代码块
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

5.继承

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

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

3.使用:

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

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

在这里插入图片描述
在这里插入图片描述
优点:
抽取出共有的重复的代码,使用继承,提高代码的复用性

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

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

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

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

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

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

为多态提供了前提

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

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

6.this和super的区别

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

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

本类的成员变量和局部变量重名,用this区分,
本类的成员变量和父类的变量重名,用super区分
在这里插入图片描述

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

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

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

要想让一个类不被其它类继承:
1.用final修饰
2.构造方法私有化
在这里插入图片描述

public  class Fu {

    public final void show(){
        System.out.println("父类中的方法,被final修饰");
    }
}

class Zi extends Fu{

   public void show(int a){

   }
}
class TestFu{
    public static void main(String[] args) {
        Zi zi = new Zi();
        zi.show();
        Fu f = new Zi();
        f.show();

    }

}
public class Hello1 {
    String s="你好";

    final static int B=6;//字面量 6 2.3  "你好"
    final  int C;

    public Hello1(int c) {
        this.C=c;
    }

    public int getB() {
        return B;
    }

    public static void main(String[] args) {
        int a=6;
        a=9;

        final int A;
        A=1;
        System.out.println(A);

    }
}

作业:
1.需求说明
使用封装实现电子宠物系统的企鹅类正确输入健康值和亲密度
保证健康值的有效性(0-100),否则取默认值60
保证亲密度的有效性(0-100),否则取默认值60
在这里插入图片描述

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;
        }

    }
}

在这里插入图片描述

package work.one;

import java.util.Scanner;

public class Test1 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("欢迎您来到宠物店! \n 请输入要领养宠物的名字:");
        String name = sc.next();
        System.out.println("请选择要领养的宠物类型:(1.狗狗  2.企鹅)");
        int i = sc.nextInt();
        if(i==1){//狗狗
            Dog dog = new Dog();
            dog.setName(name);
            System.out.println("请选择狗狗的性别:(1.Q仔  2.Q妹)");
            dog.setSex(sc.nextInt());
            System.out.println("请输入狗狗的亲密度(1~100之间):");
            dog.setLove(sc.nextInt());

            System.out.println("宠物的自白:\n 我的名字叫"+name+",健康值是"+0+",和主人的" +
                    "亲密度是"+dog.getLove()+",我的性别是"+dog.getSex());
        }else {//企鹅
            Penguin p = new Penguin();
            p.setName(name);
            System.out.println("请选择企鹅的性别:(1.Q仔  2.Q妹)");
             p.setSex(sc.nextInt());
            System.out.println("请输入企鹅的健康值(1~100之间):");
             p.setHealth(sc.nextInt());
            System.out.println("宠物的自白:\n 我的名字叫"+name+",健康值是"+p.getHealth()+",和主人的" +
                    "亲密度是"+0+",我的性别是"+p.getSex());
        }


    }
}
package work.one;

public class Penguin {
    private String name;
    private String sex;
    private int health;

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

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

    }

    public int getHealth() {
        return health;
    }

    public void setHealth(int health) {
        if(health>=0&&health<=100){
            this.health = health;
        }else {
            System.out.println("健康值应该在0-100之间,默认值是60");
            this.health = 60;
        }
    }
}
package work.one;

public class Dog {
    private String name;
    private String sex;
    private int love;

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

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

    }

    public int getLove() {
        return love;
    }

    public void setLove(int love) {
        if(love>=0&&love<=100){
            this.love = love;
        }else {
            System.out.println("亲密度应该在0-100之间,默认值是60");
            this.love = 60;
        }
    }
}

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

package com.homework.two;

public class T2TestVector {
    public static void main(String[] args) {
        System.out.println(Vector.count);
        for (int i = 0; i <100 ; i++) {
            Vector v = new Vector();
            v.count++;
        }
        System.out.println(Vector.count);
    }
}
package com.homework.two;
public class Vector {
    static int count;
}

在这里插入图片描述

3.需求说明
使用继承优化电子宠物系统,抽取父类,创建子类,在子类中使用super调用父类构造方法。(选做)

package work.three;

public class Dog extends Pet{
   /* @Override
    public void show() {
        System.out.println("宠物的自白:\n 我的名字叫"+this.getName()+",健康值是"+0+",和主人的" +
                "亲密度是"+this.getLove()+",我的性别是"+this.getSex());
    }*/



    private int love;

    public Dog(String name, int sex, int love) {
        super(name, sex);
        this.love = love;
    }

    public int getLove() {
        return love;
    }

    public void setLove(int love) {
        if(love>=0&&love<=100){
            this.love = love;
        }else {
            System.out.println("亲密度应该在0-100之间,默认值是60");
            this.love = 60;
        }
    }
}
package work.three;

public class Penguin extends Pet {

    @Override
    public void show() {
        System.out.println("宠物的自白:\n 我的名字叫"+this.getName()+",健康值是"+this.getHealth()+",和主人的" +
                "亲密度是"+0+",我的性别是"+this.getSex());
    }
    private int health;

    public Penguin(String name, int sex, int health) {
        super(name, sex);
        this.health = health;
    }

    public int getHealth() {
        return health;
    }

    public void setHealth(int health) {
        if(health>=0&&health<=100){
            this.health = health;
        }else {
            System.out.println("健康值应该在0-100之间,默认值是60");
            this.health = 60;
        }
    }
}
package work.three;

public class Pet {
    private String name;
    private String sex;

    public void show(){

    }

    public Pet(String name, int sex) {
        this.name = name;
        if(sex==1){
            this.sex = "Q仔";
        }else{
            this.sex = "Q妹";
        }
    }

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

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

    }
}
package work.three;

import java.util.Scanner;

import static java.lang.System.out;

public class Test2 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        out.println("欢迎您来到宠物店! \n 请输入要领养宠物的名字:");
        String name = sc.next();
        out.println("请选择要领养的宠物类型:(1.狗狗  2.企鹅)");
        int i = sc.nextInt();
        if(i==1){//狗狗
            out.println("请选择狗狗的性别:(1.Q仔  2.Q妹)");
            int sex=sc.nextInt();
            out.println("请输入狗狗的亲密度(1~100之间):");
            Dog dog = new Dog(name, sex, sc.nextInt());
            dog.show();
        }else {//企鹅
            out.println("请选择企鹅的性别:(1.Q仔  2.Q妹)");
            int sex=sc.nextInt();
            out.println("请输入企鹅的健康值(1~100之间):");
            Penguin p = new Penguin(name, sex, sc.nextInt());
            p.show();
        }


    }
}

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();

    }
}

在这里插入图片描述
在这里插入图片描述

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();

    }
}

在这里插入图片描述

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

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

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


public class Animal {
    private  int age;
    public void info(){
        System.out.println("今年"+age+"岁了");
    }

    public int getAge() {
        return age;
    }

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


public class Bird extends Animal {
    private  String color;



    public void color1(){
        System.out.println("我是一只"+color+"色的鸟");
    }

    public String getColor() {
        return color;
    }

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


public class Fish extends Animal {
    private  String weight;
    public void weight1(){
        System.out.println("我是一只"+weight+"斤重的鱼");
    }

    public String getWeight() {
        return weight;
    }

    public void setWeight(String weight) {
        this.weight = weight;
    }
}



import java.util.Scanner;



public class TestAnimal {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        System.out.println("请输入鱼的年龄:");
        int a=sc.nextInt();
        Fish f1 = new Fish();
        f1.setAge(a);
        System.out.println("请输入鱼的体重:");
        String a1=sc.next();
        f1.setWeight(a1);
        System.out.println("请输入鸟的年龄:");
        int b=sc.nextInt();
        Bird bird = new Bird();
        bird.setAge(b);
        System.out.println("请输入鸟的颜色:");
        String b1=sc.next();
        bird.setColor(b1);

        bird.color1();
        bird.info();

        f1.weight1();
        f1.info();
    }
}

在这里插入图片描述

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

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

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

public class Chicken extends Poultry{
        private String skill;
        public void crow(){
            System.out.println("我会"+skill);
        }

    public String getSkill() {
        return skill;
    }

    public void setSkill(String skill) {
        this.skill = skill;
    }
}
public class Duck extends Poultry {
    private String skill;
    public void swim(){
        System.out.println("我会"+skill);
    }

    public String getSkill() {
        return skill;
    }

    public void setSkill(String skill) {
        this.skill = skill;
    }
}
public class Poultry {
    private String name;
    private String food;
    private String type;

    public void fun(){
        System.out.println("我叫"+name+",是一只"+type+"!\n" +
                "我喜欢吃"+food);
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getName() {
        return name;
    }

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

    public String getFood() {
        return food;
    }

    public void setFood(String food) {
        this.food = food;
    }


}
public class TestPoultry {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        Chicken c = new Chicken();
        c.setName("喔喔");
        c.setType("芦花鸡");
        c.setFood("虫子");
        c.setSkill("打鸣");
        c.fun();
        c.crow();

        Duck d = new Duck();
        d.setName("嘎嘎");
        d.setType("斑嘴鸭");
        d.setFood("小鱼虾");
        d.setSkill("游泳");
        d.fun();
        d.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文件

Java学习顺序

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值