一、周末作业

1、完成DVD租赁系统。

2、设计一个圆类,具有属性:圆心(点)、半径。添加一个方法:判断一个圆是否包含一个点。

  1. class Circle {
  2. public Point center;
  3. public float radius;
  4. public boolean contains(Point point) {
  5. // 1. 计算圆心和这个点之间的距离平方
  6. float distance = (center.x - point.x) * (center.x - point.x) + (center.y - point.y) * (center.y - point.y);
  7. // 2. 和半径比较
  8. return distance <= radius * radius;
  9. }
  10. }
  11. class Point {
  12. public float x;
  13. public float y;
  14. }

3、编写一个玩扑克的游戏,通过数组初始化一副牌,然后通过随机数,进行洗牌。
4、设计方法,计算两个日期之间相差多少天。两个日期的年月日由参数控制。

  1. // 设计方法,计算两个日期之间相差多少天。两个日期的年月日由参数控制。
  2. static int getDelta(int fromYear, int fromMonth, int fromDay, int toYear, int toMonth, int toDay) {
  3. // 1、起始那一天,是fromYear的第几天
  4. // 2、终止那一天,是toYear的第几天
  5. // 3、计算 fromYear的1月1日 ~ toYear的1月1日相差多少天
  6. // 4、 3 + 2 - 1
  7. int fromDays = getDays(fromYear, fromMonth, fromDay);
  8. int toDays = getDays(toYear, toMonth, toDay);
  9. int days = 0;
  10. for (int y = fromYear; y < toYear; y++) {
  11. days += check(y) ? 366 : 365;
  12. }
  13. return days + toDays - fromDays;
  14. }
  15. /**
  16. * 计算一个日期是当年的第几天
  17. * @param year
  18. * @param month
  19. * @param day
  20. * @return
  21. */
  22. static int getDays(int year, int month, int day) {
  23. int days = day;
  24. for (int m = 1; m < month; m++) {
  25. if (m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12) {
  26. days += 31;
  27. }
  28. else if (m == 4 || m == 6 || m == 9 || m == 11) {
  29. days += 30;
  30. }
  31. else if (m == 2) {
  32. days += check(year) ? 29 : 28;
  33. }
  34. }
  35. return days;
  36. }
  37. /**
  38. * 验证一个年份是不是一个闰年
  39. * @param year
  40. * @return
  41. */
  42. static boolean check(int year) {
  43. return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
  44. }

二、继承

1、概念

  • 产生继承关系后, 子类可以使用父类中的属性和方法, 也可以定义子类独有的属性和方法
  • Java是单继承,
  • 使用继承,可以简化代码,提高代码的复用性,是多态的前提

    2、语法

  • 继承, 需要使用关键字 extends。

  • Object类:是java继承体系中所有类的父类,Object类没有父类.
    1. //Phone类没有显示的父类,默认父类是Object类
    2. class Phone {}
    3. //Iphone类继承自Phone类
    4. class Iphone extends Phone {
    5. }

    3、访问权限

    访问权限修饰符

    访问权限修饰符, 就是修饰类、属性的访问级别。
当前类 同包其他类 跨包子类 跨包其他类
private × × ×
default(不能写出, 不写权限, 默认就是这个权限) × ×
protected ×
public

跨包子类 访问修饰:
子类new 的是父类的,父类中的protected 方法不能访问,如果是new 子类调用父类,是可以访问父类的protected 方法。

4、需要注意的地方

不可以被继承

  • 构造方法
    • 构造方法是为了创建当前类的对象的, 不可以继承给子类。
  • 私有成员
    • 私有成员只能在当前的类中使用, 不可以继承给子类。
    • 注意:父类的私有成员,在子类中可见不可用
  • 跨包子类

    • 默认权限的属性、方法, 不可以继承给跨包的子类。

      5、方法的重写

      对父类中的方法不满意,不能满足需求,可以重写。
      @Override
      一个注解, 进行重写前的校验。 校验这个方法是否是一个重写的方法。 如果不是重写的方法, 会直接报错。
      重写的注意事项
  • 方法名字必须和父类方法名字相同

  • 参数列表必须和父类一致
  • 子类方法的访问权限需要大于等于父类方法的访问权限,父类不能是private
  • 子类方法的返回值类型需要小于等于父类方法的返回值类型—这里说的是引用类型

注意:从上面代码段show方法上可以体现出来

6、super关键字

1)一般实例化子类的时候,会调用子类的构造方法,但是在调用子类的构造方法之前,会默认调用父类中的无参数的构造方法。
2)如果父类中有多个有参数的构造方法,你需要调用哪一个,需要通过 super(xxx,xxx,xxx) ,显式的调用该方法。
3)如果父类中只有有参数的构造方法,那么子类的构造方法就必须通过super(xxx) 来调用,否则报错
4) super() 只能放在子类中的构造方法的第一行,跟this() 一样。
5) 为什么子类必须调用父类的构造方法呢? 先有父类再有子类。

7、final

概念:
最终的意思。 我们学习过的String 类就是一个final 类
1) 修饰 类 final class 类名{} 该类就没有子类
2) 修饰变量 final int a = 10 ; 该变量不能再被赋值 a = 20; 报错
3) 修饰方法 该方法不能被重写。

8、Object类(重点)

1) toString()

  1. return getClass().getName() + "@" + Integer.toHexString(hashCode());<br /> 一般打印类的对象,就是调用该类的toString 方法,调用toString 方法的目的其实就是为了打印类中的属性的信息,所以一般都重写。<br /> 利用idea工具重写非常的方便。

2) equals() a.equals(b)

默认比较的是内存地址,可以通过重写,定义自己的规则。比如String类是Object的子类,但是重写了equals方法。

3) hashCode()

    hashCode 其实就是内存地址进行了hash算法的值,方便后期通过hash码查找对象。可以简单理解为内存地址。<br />     hashCode 一般和equals 一起重写,建议的写法。两个对象如果内容一样,他们两个的地址最好也搞一样,表现为hashCode 相等即可。

4) getClass()

获取类的字节码文件 Class clazz = dog.getClass() ; 返回值是Class类,要记住。

三、多态

1、概念
多态:在代码中的描述是用父类的引用指向子类的对象。

父子关系:Student  extends  Person      Person extends  Object
//直接父类的引用指向子类对象---多态
Person person = new Student();
//Object不是Student的直接父类,但是是间接父类,这里也是多态
Object o = new Student();



List list = new ArrayList();
package com.qfedu.day05_03;

/**
 * @Author laoyan
 * @Description TODO
 * @Date 2022/3/7 14:52
 * @Version 1.0
 */
class Animal{
    public void eat() {
        System.out.println("动物吃");
    }
}

class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }
}

class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫吃");
    }
}
class Pig extends Animal{
    @Override
    public void eat() {
        System.out.println("猪猪吃.....");
    }
}

/**
 *      Fly  接口
 *     class  Bird implements Fly{
 *          fly(){
 *
 *          }
 *      }
 *      class Pig implements Fly{
 *          fly(){
 *
 *          }
 *      }
 *      Fly pig =new Pig();
 *      Fly bird =new Bird();
 *
 */
public class TestDuoTai {

    //喂狗,喂猫,喂动物
    public static void feedAnimal(Animal animal) {//animal = dog = new Dog()   多态
        animal.eat();
    }

    public static void main(String[] args) {
        Animal animal = new Animal();
        Dog dog = new Dog();
        Animal dog2 = new Dog();
        animal.eat();
        dog.eat();
        dog2.eat();
        feedAnimal(dog);
        feedAnimal(dog2);
    }
}

多态:可以通过继承来实现。
好处:
1、节约代码
2、易于拓展
2、类型转换

        Dog dog = new Dog();
        Animal animal =  dog; // 向上转型,自动转换,无需任何操作(隐式转换)
        Dog dog2 = (Dog) animal; // Animal 类型 转换为 Dog  向下转型,需要强制转换

        if(animal instanceof  Cat){
            Cat cat = (Cat) animal;// 此处报错
        }

image.png

3、instanceof 用法

 /*
            instanceOf  三个用法
            判断一个对象是否是某个类的实例化对象
            判断某个对象是否是某个类的子类对象
            判断某个对象是否是某个接口的实例化对象
         */

        System.out.println(dog instanceof Dog);
        System.out.println(dog instanceof Animal);
        //System.out.println(bird instanceof Fly);

4、多态
变量多态、参数多态、返回值多态

变量的多态:
    Person p =new Worker();

参数的多态:
   public void showPerson(Person p){

   }
 返回值多态:
   public Person newRen(int num){
       if(num==1){
         return new Worker();
       }
       if(num == 2){
          return new Student();
       }
   }

5、抽象类

抽象类:
1) abstract 修饰 class 抽象类
2) 抽象类中可以有普通方法也可以有抽象方法,不一定非得有抽象方法
3) 有抽象方法的类,必须是抽象类
4) 抽象类不能直接实例化
5) 子类继承一个抽象类,必须实现抽象类中的所有抽象方法。

注意事项:

 比较:final,abstract,static,private

- 三个都是不能与abstract同时存在的关键字
- final:被final修饰的类不能有子类,方法不能重写,但是abstract必须有子类,必须重写
- static:修饰的方法可以通过类名调用,abstract必须通过子类实现
- private:修饰的方法不能重写,abstract必须重写