类和对象(中级)

在这里插入图片描述

访问修饰符,快捷键使用

在这里插入图片描述

// 冒泡排序
/*
1.源码文件都写在src目录下
2.编译后会生成out文件夹, 存放 .class 可执行文件, 每个类对应一个
3.包相当于一个文件夹, 便于管理源码, 包外文件可以导入包调用包里的类
4.程序开头的 package 用来声明当前类所在的包

#快捷键使用#
1. alt + / 补全代码
2. ctrl + shift + L  自动对其代码
3. shift +F10  快速运行代码
4. Ctrl + h 看类的继承关系
5. Ctrl + b 快速定位方法位置
6. new 类型.var 自动生成变量名
#常用模板#
1. sout 快速打印输出语句
2. main 主函数
3. fori 以i为变量的for循环

#访问修饰符#
1.public 对外公开
2.protected 对子类和同一个包的类公开
3.无修饰符, 对同一个包的类公开
4.private 只有类本身可以访问
* */


import java.util.Arrays;

public class Test {
    public static void main(String[] args) {
        int[] A = {8, 7, 10, 5, 1, 3, 15};
        // 自己编写方法进行排序
        maopao(A);
        int[] B = {10, 7, 16, 5, 8, 3, 22};
        // 通过Arrays包中的sort方法排序
        Arrays.sort(B);

        System.out.print("排序后数组为:");
        for(int i = 0; i < A.length; i++){
            System.out.print(A[i] + " ");
        }
        System.out.println();
        for(int i = 0; i < B.length; i++){
            System.out.print(B[i] + " ");
        }
        System.out.println();
    }

    // 编写冒泡排序的方法
    static void maopao(int[] A){
        for(int i = 0; i < A.length; i++){
            for(int j = i + 1; j < A.length; j++){
                if(A[i] > A[j]){
                    int f = A[i];
                    A[i] = A[j];
                    A[j] = f;
                }
            }
        }
        return ;
    }

}

面向对象三大特征

封装

// 封装
/*
定义:封装指把抽象的属性和方法封装在一起, 数据被保护在内部, 通过背授权
     的方法对数据进行操作
#实现步骤#
1.把属性进行私有化 private
2.提供 public set方法, 对属性判断并赋值
3.提供一个 public get 方法, 获取属性的值
4.若使用构造方法, 则可以在构造方法中调用 set 方法
* */
public class FengZhuang {
    public static void main(String[] args) {
        Person person = new Person();
        // 调用 set 给属性赋值
        person.setName("神里绫华");
        person.setAge(18);
        person.setSalary(520521);
        System.out.println(person.info());
        // 使用构造器调用 set 方法
        Person person1 = new Person("宵宫", 101, 1314);
        System.out.println(person1.info());
    }
}

class Person{
    public String name;
    // 年龄和工资私有化
    private int age;
    private double salary;
    public String info(){
        return "姓名 " + this.name + " 年龄 " + this.age
                + " 工资 " + this.salary;
    }
    public Person(String name, int age, double salary){
        // 在构造方法中调用 set 方法判断是否合法
        setName(name);
        setAge(age);
        setSalary(salary);
    }
    public Person(){
    }

    // 右键生成get 和 set 方法
    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 >=1 && age <= 100){
            this.age = age;
        }
        else{
            System.out.println("年龄不符合规定");
            // 给个默认的年龄
            this.age = 22;
        }
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }
}

继承

// 类的继承
/*
使用: 定义子类时在后面添加 extends + 父类
要点:
1.子类继承父类所有属性和方法, 非私有属性和方法在子类里可直接访问,
  私有属性通过父类公共方法去访问
2.当创建子类对象时, 默认先调用父类的无参构造器, 若父类中已经重写
  构造器, 则在每个子类构造器中都要用 super(父类构造器参数)指定构造器
3.子类构造器调用某个父类构造器, 使用 super(参数), 且必须写在第一行,
  且 super 只能在构造器中使用, 不能和 this() 共存
4.java中所有类都是Object类的子类, 父类构造器调用要追溯到 Object 类
5.一个类只能继承一个类, 若需要继承多个类, 则通过父类继承另一个类达成
6.若一个类包括其父类有同一个属性, 则调用时采取就近原则, 自己->爹->爷
* */

package JiCheng;

public class Test {
    // 定义四个不同访问权限的值
    public int n1 = 100;
    protected int n2 = 200;
    int n3 = 300;
    private int n4 = 400;

    public Test(){
        System.out.println("调用无参父类构造器");
    }
    public Test(int a1, int a2){
        System.out.println("调用有参父类构造器");
    }
    // 子类通过 get 访问私有属性 n4
    public int getN4() {
        return n4;
    }
}

// 子类
/*
#super使用#
(在同名时区分父类与子类)
1.访问父类的属性 super.属性名
2.访问父类的方法 super.方法名(参数)
3.访问父类构造器 super(参数),和访问本类构造器 this(参数)  (第一句且只能有一个)
* */
package JiCheng;

public class Son1 extends Test{ // 继承父类Test
    public Son1(){
        System.out.println("调用son1无参构造器");
    }
    public Son1(int a1, int a2){
        // 使用 super 指定需要调用的父类构造器
        super(a1, a2);
        System.out.println("调用son1有参构造器");
    }
    // 访问父类的属性
    public void prt(){
        System.out.println("父类属性:" + "n1=" + n1 +
                " n2=" + n2 + " n3=" + n3);
        System.out.println(" n4=" + getN4());
    }
}

在这里插入图片描述

继承中方法的重写

在这里插入图片描述

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

public class Animal {
    String name = "动物";
    int age = 10;
    public void sleep(){
        System.out.println("睡觉觉");
    }
    public void run(){
        System.out.println("跑步步");
    }
    public void eat(){
        System.out.println("吃饭饭");
    }
    public void show(){
        System.out.println("你好呀");
    }
}

public class Cat extends Animal{
    public void eat(){
        System.out.println("小猫吃鱼");
    }
    public void catchMouth(){
        System.out.println("猫爪老鼠");
    }
}

多态

对象的上下转型

在这里插入图片描述

/* 多态

1.对象编译类型和运行类型可能不一致, 创建对象时可以指向其的子类

#向上转型#
2.语法: 父类类型 引用名 = new 子类类型,
  等号左边是编译类型, 右边运行类型(可变)
  编译时认为是Animal, 运行时是Dog
3.该animal对象可以调用父类所有成员, 但不能调用子类特有的成员, 调用方法时
  从子类向上查找

#向下转型#
4.语法:子类类型 引用名 = (子类类型) 父类引用,
  只能强转父类的引用, 不能强转父类的对象
  父类引用必须是指向当前目标类型的对象
  向下转型之后可以调用子类中所有成员

* */

package DuoTai;

public class Mainc {
    public static void main(String[] args) {
        // 向上转型, 父类的引用指向子类的对象
        // animal 可以调用父类所有属性方法, 但不能调用子类特有的成员
        Animal animal = new Cat();
        animal.sleep();
        animal.eat(); // 向上转型:方法看子类(运行), 属性看父类(编译)
        animal.show(); // 子类没有则看父类

        // 向下转型
        Cat cat = (Cat) animal;
        // 把 Animal 强转为 Cat 对象, 可调用Cat的特有方法
        cat.catchMouth();
    }
}

举例

// 父类
public class Employee {
    public String name;
    public double salary;
    public double getAnnual(){
        return salary * 12;
    }
}
// 经理类
public class JingLi extends Employee{
    public double bonus;
    public JingLi(String n, double s, double b){
        this.name = n;
        this.salary = s;
        this.bonus = b;
    }

    public void manage(){
        System.out.println("经历管理员工中");
    }

    @Override
    public double getAnnual() {
        return super.getAnnual() + bonus;
    }
}
// 普通员工类
public class PuGong extends Employee{
    public PuGong(String n, double s){
        this.name = n;
        this.salary = s;
    }

    public void work(){
        System.out.println("员工工作中");
    }

    @Override
    public double getAnnual() {
        return super.getAnnual();
    }
}
// 主方法
public class mainc {
    public static void main(String[] args) {
        // 向上转型
        Employee e1 = new PuGong("jack", 2000);
        Employee e2 = new JingLi("mary", 3000, 1000);
        mainc m = new mainc();
        m.showAnnual(e1);
        m.showAnnual(e2);
        m.showWork(e1);
        m.showWork(e2);
    }

    // 获取每个员工的工作状态
    public void showWork(Employee e){
        if(e instanceof PuGong){
            PuGong p = (PuGong) e;
            p.work();
        }
        else if(e instanceof JingLi){
            JingLi j = (JingLi) e;
            j.manage();
        }
        else {
            System.out.println("类型错误");
            return ;
        }
    }
}

动态绑定机制

在这里插入图片描述

/*
动态绑定
1.当调用对象方法时, 该方法会和该对象的内存地址(运行类型)绑定
  只要调用方法都从运行类型开始找, 即使父类中调用父类和子类都有的方法
2.当调用对象属性时, 没有动态绑定机制, 哪里声明哪里用
* */

package DuoTai;

public class DongTaiBangDing {
    public static void main(String[] args) {
        A a = new B();
        System.out.println(a.sum());
        System.out.println(a.sum1());
    }
}

class A{
    public int i =10;
    public int sum(){
// 子类中没有 sum 方法, 固调用父类中的, 又调用getI方法先从子类中找
        return getI() + 10;
    }
    public int sum1(){
        return i + 10;
    }
    public int getI(){
        return i;
    }
}

class B extends A{
    public int i = 20;

    // 父类调用 getI 优先找运行类型, i是属性, 采取就近原则
    public int getI() {
        return i;
    }
}

Object 方法重写

// # ==和equals(重写) #
/*
使用 Ctrl+B 查看源码, 或右键-> 转到(go to)-> 声明

1. == 若判断基本类型, 判断的是值是否相等
2. == 若判定引用类型, 判断地址是否相等, 即是不是一个对象
* */

package DuoTai;

import java.util.Objects;

public class Equals {
    public static void main(String[] args) {
        // equals 是Object类中的方法, 只能判断引用类型地址是否相等
        // 其子类对 equals 方法重写, 判断数据是否相等, 下为 String 类重写
        "a".equals("b");
        Integer integer = new Integer(1000);
        Integer integer1 = new Integer(1000);
        System.out.println(integer == integer1); // 判断地址
        System.out.println(integer.equals(integer1)); // 判断值是否相等

        // equals 方法的重写, 判断两个person类是否相等
        Person person1 = new Person("jack", 18, "男");
        Person person2 = new Person("Mary", 18, "女");
        System.out.println(person1.equals(person2));

        // toString 重写, 该方法在Object 中返回 全类名+@+十六进制哈希值
        System.out.println("toString 结果:" + person1.toString());
        // 重写前 :DuoTai.Person@ba6817e3
        // 重写后: 一般是输出属性值
    }
}

class Person{
    String name;
    int age;
    String sex;
    public Person(String name, int age, String sex){
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
    // 对 equals 方法进行重写
    @Override
    public boolean equals(Object o) { // 传进的类为 Object!
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        // getClass() 获取对象的类型
        Person person = (Person) o; // 向下转型
        return age == person.age && Objects.equals(name, person.name) && Objects.equals(sex, person.sex);
    }

    // 两个引用指向同一个对象 哈希值相同, 不指向一个对象则不同
    @Override
    public int hashCode() {
        return Objects.hash(name, age, sex);
    }

    // 重写后: 一般是输出属性值, 在输出对象时默认调用该方法
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                '}';
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值