一、周末作业
1、完成DVD租赁系统。
2、设计一个圆类,具有属性:圆心(点)、半径。添加一个方法:判断一个圆是否包含一个点。
class Circle {
public Point center;
public float radius;
public boolean contains(Point point) {
// 1. 计算圆心和这个点之间的距离平方
float distance = (center.x - point.x) * (center.x - point.x) + (center.y - point.y) * (center.y - point.y);
// 2. 和半径比较
return distance <= radius * radius;
}
}
class Point {
public float x;
public float y;
}
3、编写一个玩扑克的游戏,通过数组初始化一副牌,然后通过随机数,进行洗牌。
4、设计方法,计算两个日期之间相差多少天。两个日期的年月日由参数控制。
// 设计方法,计算两个日期之间相差多少天。两个日期的年月日由参数控制。
static int getDelta(int fromYear, int fromMonth, int fromDay, int toYear, int toMonth, int toDay) {
// 1、起始那一天,是fromYear的第几天
// 2、终止那一天,是toYear的第几天
// 3、计算 fromYear的1月1日 ~ toYear的1月1日相差多少天
// 4、 3 + 2 - 1
int fromDays = getDays(fromYear, fromMonth, fromDay);
int toDays = getDays(toYear, toMonth, toDay);
int days = 0;
for (int y = fromYear; y < toYear; y++) {
days += check(y) ? 366 : 365;
}
return days + toDays - fromDays;
}
/**
* 计算一个日期是当年的第几天
* @param year
* @param month
* @param day
* @return
*/
static int getDays(int year, int month, int day) {
int days = day;
for (int m = 1; m < month; m++) {
if (m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12) {
days += 31;
}
else if (m == 4 || m == 6 || m == 9 || m == 11) {
days += 30;
}
else if (m == 2) {
days += check(year) ? 29 : 28;
}
}
return days;
}
/**
* 验证一个年份是不是一个闰年
* @param year
* @return
*/
static boolean check(int year) {
return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
}
二、继承
1、概念
- 产生继承关系后, 子类可以使用父类中的属性和方法, 也可以定义子类独有的属性和方法
- Java是单继承,
-
2、语法
继承, 需要使用关键字 extends。
- Object类:是java继承体系中所有类的父类,Object类没有父类.
//Phone类没有显示的父类,默认父类是Object类
class Phone {}
//Iphone类继承自Phone类
class Iphone extends Phone {
}
3、访问权限
访问权限修饰符
访问权限修饰符, 就是修饰类、属性的访问级别。
当前类 | 同包其他类 | 跨包子类 | 跨包其他类 | |
---|---|---|---|---|
private | √ | × | × | × |
default(不能写出, 不写权限, 默认就是这个权限) | √ | √ | × | × |
protected | √ | √ | √ | × |
public | √ | √ | √ | √ |
跨包子类 访问修饰:
子类new 的是父类的,父类中的protected 方法不能访问,如果是new 子类调用父类,是可以访问父类的protected 方法。
4、需要注意的地方
不可以被继承
- 构造方法
- 构造方法是为了创建当前类的对象的, 不可以继承给子类。
- 私有成员
- 私有成员只能在当前的类中使用, 不可以继承给子类。
- 注意:父类的私有成员,在子类中可见不可用
跨包子类
方法名字必须和父类方法名字相同
- 参数列表必须和父类一致
- 子类方法的访问权限需要大于等于父类方法的访问权限,父类不能是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()
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;// 此处报错
}
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必须重写