40-面向对象编程(中级部分)-1

idea快捷键

  1. 删除当前行,默认时ctrl + r
  2. 复制当前行:ctrl + D
  3. 补全代码:alt + /
  4. 添加注释和取消注释:ctrl + /
  5. 导入该行需要的类:alt + enter
  6. 快速格式化代码:ctrl + alt + L
  7. 快速运行程序alt + R
  8. 生成构造器:alt + insert
  9. 查看一个类的层级关系:ctrl + H
  10. 将光标放在一个方法上,输入ctrl + B ,可以定位到方法
  11. 自动的分配变量名,通过后面加 .var

包的三大作用

  1. 区分相同名字的类
  2. 当类很多的时候。可以很好的管理类
  3. 控制访问范围

包的基本用法

package com.xxxx;

  1. package 关键字,表示打包
  2. com.xxxx : 表示 包名

包的本质分析(原理)

实际上就是创建不同的文件夹来保存类文件
请添加图片描述

包的命名

  • 命名规则
    只能包含数字,字母,下划线,小圆点,但不能数字开头,不能是关键字或保留字
    请添加图片描述

  • 命名规范
    一般是小写字母+小圆点
    com.公司名.项目名.业务模块名;
    请添加图片描述

常用的包

一个包下,包含很多的类,java中常用的包有:
请添加图片描述

引入包

请添加图片描述

package com.hspedu.pkg;

import java.util.Arrays;

//注意:
//老韩建议:我们需要使用到哪个类,就导入哪个类即可,不建议使用 *导入
//import java.util.Scanner; //表示只会引入java.util 包下的 Scanner
//import java.util.*;//表示将java.util 包下的所有类都引入(导入)
public class Import01 {

    public static void main(String[] args) {

        //使用系统提供 Arrays 完成 数组排序
        int[] arr = {-1, 20, 2, 13, 3};
        //比如对其进行排序
        //传统方法是,自己编写排序(冒泡)
        //系统是提供了相关的类,可以方便完成 Arrays
        Arrays.sort(arr);
        //输出排序结果
        for (int i = 0; i < arr.length ; i++) {
            System.out.print(arr[i] + "\t");
        }
    }
}

包的注意事项

请添加图片描述

//package的作用是声明当前类所在的包,需要放在类(或者文件)的最上面,
// 一个类中最多只有一句package

package com.hspedu.pkg;

//import指令 位置放在package的下面,在类定义前面,可以有多句且没有顺序要求
import java.util.Scanner;
import java.util.Arrays;

//...

//类定义
public class PkgDetail {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int[] arr = {0, -1, 1};
        Arrays.sort(args);
    }
}

请添加图片描述

访问修饰符

基本介绍

请添加图片描述

4种访问修饰符的访问范围

请添加图片描述

使用的注意事项

请添加图片描述
这里可以看看老师的原视频讲解

封装

封装介绍

请添加图片描述

封装的理解和好处

  1. 隐藏现实细节:方法(接入数据库)<-调用(传入参数)
  2. 可以对数据进行验证,保证合理安全

封装的实现步骤(三步)

  1. 将属性进行私有化private(不能直接修改属性)
  2. 提供一个公共的(public)set方法,用于对属性判断并赋值
public void setXxx(类型 参数名){//Xxx表示某个属性
	//加入数据验证的业务逻辑
	属性 == 参数名;
}

  1. 提供一个公共的(public)get方法,用于获取属性的值
public 数据类型 getXxx(类型 参数名){//Xxx表示某个属性
	return Xxx
}

快速入门

package com.hspedu.encap;

public class Encapsulation01 {

    public static void main(String[] args) {
        //如果要使用快捷键alt+r, 需要先配置主类
        //第一次,我们使用鼠标点击形式运算程序,后面就可以用
        Person person = new Person();
        person.setName("韩顺平");
        person.setAge(30);
        person.setSalary(30000);
        System.out.println(person.info());
        System.out.println(person.getSalary());

        //如果我们自己使用构造器指定属性
        Person smith = new Person("smith", 80, 50000);
        System.out.println("====smith的信息======");
        System.out.println(smith.info());


    }
}
/*
那么在java中如何实现这种类似的控制呢?
请大家看一个小程序(com.hspedu.encap: Encapsulation01.java),
不能随便查看人的年龄,工资等隐私,并对设置的年龄进行合理的验证。年龄合理就设置,否则给默认
年龄, 必须在 1-120, 年龄, 工资不能直接查看 , name的长度在 2-6字符 之间

 */
class Person {
    public  String name; //名字公开
    private int age; //age 私有化
    private double salary; //..

    public void say(int n,String name) {

    }
    //构造器 alt+insert
    public Person() {
    }
    //有三个属性的构造器
    public Person(String name, int age, double salary) {
//        this.name = name;
//        this.age = age;
//        this.salary = salary;
        //我们可以将set方法写在构造器中,这样仍然可以验证
        setName(name);
        setAge(age);
        setSalary(salary);
    }

    //自己写setXxx 和 getXxx 太慢,我们使用快捷键
    //然后根据要求来完善我们的代码.
    public String getName() {
        return name;
    }
    public void setName(String name) {
        //加入对数据的校验,相当于增加了业务逻辑
        if(name.length() >= 2 && name.length() <=6 ) {
            this.name = name;
        }else {
            System.out.println("名字的长度不对,需要(2-6)个字符,默认名字");
            this.name = "无名人";
        }
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        //判断
        if(age >= 1 && age <= 120) {//如果是合理范围
            this.age = age;
        } else {
            System.out.println("你设置年龄不对,需要在 (1-120), 给默认年龄18 ");
            this.age = 18;//给一个默认年龄
        }
    }

    public double getSalary() {
        //可以这里增加对当前对象的权限判断
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }
    //写一个方法,返回属性信息
    public String info() {
        return "信息为 name=" + name  + " age=" + age + " 薪水=" + salary;
    }
}

课后练习

请添加图片描述

package com.hspedu.encap;

public class TestAccount {
    public static void main(String[] args) {
        //创建Account
        Account account = new Account();
        account.setName("jack");
        account.setBalance(60);
        account.setPwd("123456");

        account.showInfo();
    }
}

package com.hspedu.encap;

/**
 * 创建程序,在其中定义两个类:Account和AccountTest类体会Java的封装性。
 * Account类要求具有属性:姓名(长度为2位3位或4位)、余额(必须>20)、
 * 密码(必须是六位), 如果不满足,则给出提示信息,并给默认值(程序员自己定)
 * 通过setXxx的方法给Account 的属性赋值。
 * 在AccountTest中测试
 */
public class Account {
    //为了封装,将3个属性设置为private
    private String name;
    private double balance;
    private String pwd;

    //提供两个构造器
    public Account() {
    }

    public Account(String name, double balance, String pwd) {
        this.setName(name);
        this.setBalance(balance);
        this.setPwd(pwd);
    }

    public String getName() {
        return name;
    }

    //姓名(长度为2位3位或4位)
    public void setName(String name) {
        if (name.length() >= 2 && name.length() <= 4) {
            this.name = name;
        } else {
            System.out.println("姓名要求(长度为2位3位或4位),默认值 无名");
            this.name = "无名";
        }
    }

    public double getBalance() {
        return balance;
    }

    //余额(必须>20)
    public void setBalance(double balance) {
        if (balance > 20) {
            this.balance = balance;
        } else {
            System.out.println("余额(必须>20) 默认为0");
        }
    }

    public String getPwd() {
        return pwd;
    }

    //密码(必须是六位)
    public void setPwd(String pwd) {
        if (pwd.length() == 6) {
            this.pwd = pwd;
        } else {
            System.out.println("密码(必须是六位)默认密码为 000000");
            this.pwd = "000000";
        }
    }
    //显示账号信息
    public void showInfo() {
        //可以增加权限的校验
        System.out.println("账号信息 name=" + name + " 余额=" + balance + " 密码" + pwd);
//        if() {
//            System.out.println("账号信息 name=" + name + " 余额=" + balance + " 密码");
//        }else{
//            System.out.println("你无权查看...");
//        }
    }
}

继承

基本介绍和示意图

请添加图片描述
请添加图片描述

基本语法

class 子类 extends 父类{
}
  1. 子类就会自动拥有父类定义的属性和方法
  2. 父类又叫超类,基类
  3. 子类又叫派生类

快速入门

package com.hspedu.extend_.improve_;

import com.hspedu.extend_.Graduate;
import com.hspedu.extend_.Pupil;

public class Extends01 {
    public static void main(String[] args) {
        com.hspedu.extend_.Pupil pupil = new Pupil();
        pupil.name = "银角大王~";
        pupil.age = 11;
        pupil.testing();
        pupil.setScore(50);
        pupil.showInfo();

        System.out.println("=======");
        com.hspedu.extend_.Graduate graduate = new Graduate();
        graduate.name = "金角大王~";
        graduate.age = 23;
        graduate.testing();
        graduate.setScore(80);
        graduate.showInfo();
    }
}
package com.hspedu.extend_.improve_;

//父类,是Pupil 和 Graduate的父类
public class Student {
    //共有属性
    public String name;
    public int age;
    private double score;//成绩
    //共有的方法
    public void setScore(double score) {
        this.score = score;
    }

    public void showInfo() {
        System.out.println("学生名 " + name + " 年龄 " + age + " 成绩 " + score);
    }
}
package com.hspedu.extend_.improve_;

//让Pupil 继承 Student类
public class Pupil extends Student {
    public void testing() {
        System.out.println("小学生 " + name + "  正在考小学数学..");
    }
}

package com.hspedu.extend_.improve_;

public class Graduate extends Student {

    public void testing() {//和Pupil不一样
        System.out.println("大学生 " + name + " 正在考大学数学..");
    }
}

继承给编程带来的便利

  1. 代码的复用性提高了
  2. 代码的扩展性和维护性提高了

细节

  1. 子类继承了所有的属性和方法,非私有的属性和方法可以在子类中直接访问,但是私有属性和方法不能在子类中直接访问,用通过父类提供的公共方法去访问
  2. 子类必须调用父类的构造器,完成父类初始化
  3. 当创建子类对象时,不管使用子类的哪个构造器。默认情况下总会去调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用super去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译不通过
  4. 如果希望指定去调用父类的某个构造器,则显示的调用一个super(参数列表)
  5. super在使用时,必须放在构造器第一行(super只能在构造器中使用)
  6. super()和this()都只能放在构造器第一行,因此两个方法不能存在一个构造器
  7. java所有类都是Object类的子类,Object是所有类的基类
    请添加图片描述
  8. 父类构造器的调用不限于直接父类,将一直往上追溯直到Object(顶级父类)
  9. 子类最多只能继承一个父类(指直接继承)即java中是单继承机制
    10.不能滥用继承,子类和父类之间必须满足is-a的逻辑关系

继承的本质分析

案例:

package com.hspedu.extend_;

/**
 * 讲解继承的本质
 */
public class ExtendsTheory {
    public static void main(String[] args) {
        Son son = new Son();//内存的布局
        //?-> 这时请大家注意,要按照查找关系来返回信息
        //(1) 首先看子类是否有该属性
        //(2) 如果子类有这个属性,并且可以访问,则返回信息
        //(3) 如果子类没有这个属性,就看父类有没有这个属性(如果父类有该属性,并且可以访问,就返回信息..)
        //(4) 如果父类没有就按照(3)的规则,继续找上级父类,直到Object...
        System.out.println(son.name);//返回就是大头儿子
        //System.out.println(son.age);//返回的就是39
        //System.out.println(son.getAge());//返回的就是39
        System.out.println(son.hobby);//返回的就是旅游
    }
}

class GrandPa { //爷类
    String name = "大头爷爷";
    String hobby = "旅游";
}

class Father extends GrandPa {//父类
    String name = "大头爸爸";
    private int age = 39;

    public int getAge() {
        return age;
    }
}

class Son extends Father { //子类
    String name = "大头儿子";
}


内存分布图:
请添加图片描述

课后练习

请添加图片描述

package com.hspedu.extend_.exercise;

public class ExtendsExercise03 {
    public static void main(String[] args) {
        PC pc = new PC("intel", 16, 500, "IBM");
        pc.printInfo();
    }
}
/*
编写Computer类,包含CPU、内存、硬盘等属性,getDetails方法用于返回Computer的详细信息
编写PC子类,继承Computer类,添加特有属性【品牌brand】
编写NotePad子类,继承Computer类,添加特有属性【color】//同学们自己写。
编写Test类,在main方法中创建PC和NotePad对象,分别给对象中特有的属性赋值,
以及从Computer类继承的属性赋值,并使用方法并打印输出信息
 */

package com.hspedu.extend_.exercise;

//编写Computer类,包含CPU、内存、硬盘等属性,getDetails方法用于返回Computer的详细信息
public class Computer {
    private String cpu;
    private int memory;
    private int disk;
    public Computer(String cpu, int memory, int disk) {
        this.cpu = cpu;
        this.memory = memory;
        this.disk = disk;
    }
    //返回Computer信息
    public String getDetails() {
        return "cpu=" + cpu + " memory=" + memory + " disk=" + disk;
    }

    public String getCpu() {
        return cpu;
    }

    public void setCpu(String cpu) {
        this.cpu = cpu;
    }

    public int getMemory() {
        return memory;
    }

    public void setMemory(int memory) {
        this.memory = memory;
    }

    public int getDisk() {
        return disk;
    }

    public void setDisk(int disk) {
        this.disk = disk;
    }
}

package com.hspedu.extend_.exercise;

//编写PC子类,继承Computer类,添加特有属性【品牌brand】

public class PC extends Computer{

    private String brand;
    //这里IDEA 根据继承的规则,自动把构造器的调用写好
    //这里也体现: 继承设计的基本思想,父类的构造器完成父类属性初始化
    //子类的构造器完成子类属性初始化
    public PC(String cpu, int memory, int disk, String brand) {
        super(cpu, memory, disk);
        this.brand = brand;
    }
    public String getBrand() {
        return brand;
    }
    public void setBrand(String brand) {
        this.brand = brand;
    }
    public void printInfo() {
        System.out.println("PC信息=");
//        System.out.println(getCpu() + getMemory() + getDisk());
        //调用父类的getDetails方法,得到相关属性信息..
        System.out.println(getDetails() + " brand=" + brand);
    }

}

注:这里两个类最后都返回自己的信息方便一次调用

super关键字

基本介绍

super代表父类的引用,用于访问父类的属性,方法,构造器

基本语法

请添加图片描述

例子和细节在一起

细节

请添加图片描述
请添加图片描述

package com.hspedu.super_;

public class A extends Base{
    //4个属性
    //public int n1 = 100;
    protected int n2 = 200;
    int n3 = 300;
    private int n4 = 400;

    public A() {}
    public A(String name) {}
    public A(String name, int age) {}

//    public void cal() {
//        System.out.println("A类的cal() 方法...");
//    }

    public void test100() {
    }

    protected void test200() {
    }

    void test300() {
    }

    private void test400() {
    }
}


package com.hspedu.super_;

public class B extends A {

    public int n1 = 888;

    //编写测试方法
    public void test() {
        //super的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用super去访问爷爷类的成员;
        // 如果多个基类(上级类)中都有同名的成员,使用super访问遵循就近原则。A->B->C

        System.out.println("super.n1=" + super.n1);
        super.cal();
    }

    //访问父类的属性 , 但不能访问父类的private属性 [案例]super.属性名
    public void hi() {
        System.out.println(super.n1 + " " + super.n2 + " " + super.n3 );
    }
    public void cal() {
        System.out.println("B类的cal() 方法...");
    }
    public void sum() {
        System.out.println("B类的sum()");
        //希望调用父类-A 的cal方法
        //这时,因为子类B没有cal方法,因此我可以使用下面三种方式

        //找cal方法时(cal() 和 this.cal()),顺序是:
        // (1)先找本类,如果有,则调用
        // (2)如果没有,则找父类(如果有,并可以调用,则调用)
        // (3)如果父类没有,则继续找父类的父类,整个规则,就是一样的,直到 Object类
        // 提示:如果查找方法的过程中,找到了,但是不能访问, 则报错, cannot access
        //      如果查找方法的过程中,没有找到,则提示方法不存在
        //cal();
        this.cal(); //等价 cal

        //找cal方法(super.call()) 的顺序是直接查找父类,其他的规则一样
        //super.cal();

        //演示访问属性的规则
        //n1 和 this.n1 查找的规则是
        //(1) 先找本类,如果有,则调用
        //(2) 如果没有,则找父类(如果有,并可以调用,则调用)
        //(3) 如果父类没有,则继续找父类的父类,整个规则,就是一样的,直到 Object类
        // 提示:如果查找属性的过程中,找到了,但是不能访问, 则报错, cannot access
        //      如果查找属性的过程中,没有找到,则提示属性不存在
        System.out.println(n1);
        System.out.println(this.n1);

        //找n1 (super.n1) 的顺序是直接查找父类属性,其他的规则一样
        System.out.println(super.n1);

    }
    //访问父类的方法,不能访问父类的private方法 super.方法名(参数列表);
    public void ok() {
        super.test100();
        super.test200();
        super.test300();
        //super.test400();//不能访问父类private方法
    }
    //访问父类的构造器(这点前面用过):super(参数列表);只能放在构造器的第一句,只能出现一句!
    public  B() {
        //super();
        //super("jack", 10);
        super("jack");
    }
}

package com.hspedu.super_;

public class Base { //父类是Object

    public int n1 = 999;
    public int age = 111;
    public void cal() {
        System.out.println("Base类的cal() 方法...");
    }
    public void eat() {
        System.out.println("Base类的eat().....");
    }
}

请添加图片描述

面向对象编程-继承

请添加图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值