1、昨日复习

  1. 什么是多态性?什么是虚拟方法调用?
    对象的多态性:父类的引用指向子类的对象。
    Person p = new Man();
    p.eat();
    调用方法时,编译时看左边,运行时看右边。
    2. 一个类可以有几个直接父类?(只有一个)一个父类可有多少个子类?(多个)子类能获取直接父类的父类中的结构吗?(可以)子类能否获取父类中private权限的属性或方法?(可以的)
    A is a B
    3. 方法的重写(override/overwrite)的具体规则有哪些?
    方法名、形参列表相同
    权限修饰符
    返回值
    抛出的异常

  2. super调用构造器,有哪些具体的注意点
    this(形参列表):本类重载的其它的构造器
    super(形参列表):调用父类中指定的构造器
    n n – 1 1

  3. 在下面的代码结构中:使用关键字:this,super;方法的重写;继承;

    QQ截图20211220151843.png

    2、对象类型转换

    对Java对象的强制类型转换称为造型
    从子类到父类的类型转换可以自动进行
    从父类到子类的类型转换必须通过造型(强制类型转换)实现
    无继承关系的引用类型间的转换是非法的
    在造型前可以使用instanceof操作符测试一个对象的类型
    QQ截图20211220164533.png
    注意:Person p = new Person();不能强转成子类Student
    Person p = new Student();可以强转成子类

    3、instanceof 操作符

    x instanceof A:检验x是否为类A的对象,返回值为boolean型。
    使用情景:为了避免在向下转型时出现ClassCastException的异常,我们在向下转型之前,先进行instanceof的判断,一旦返回true,就进行向下转型;如果返回false,不进行向下转型。
    要求x所属的类与类A必须是子类和父类的关系,否则编译错误。

若子类重写了父类方法,就意味着子类里定义的方法彻底覆盖了父类里的同名方法,系统将不可能把父类里的方法转移到子类中。
对于实例变量则不存在这样的现象,即使子类里定义了与父类完全相同的实例变量,这个实例变量依然不可能覆盖父类中定义的实例变量

  1. package com.atguigu.java;
  2. /*
  3. 建立InstanceTest 类,在类中定义方法
  4. method(Person e);
  5. 在method中:
  6. (1)根据e的类型调用相应类的getInfo()方法。
  7. (2)根据e的类型执行:
  8. 如果e为Person类的对象,输出: “a person”;
  9. 如果e为Student类的对象,输出:
  10. “a student”
  11. “a person ”
  12. 如果e为Graduate类的对象,输出:
  13. “a graduated student”
  14. “a student”
  15. “a person”
  16. */
  17. public class InstanceTest {
  18. public void method(Person e) {
  19. System.out.println(e.getInfo());
  20. if (e instanceof Graduate) {
  21. System.out.println("a graduated student");
  22. System.out.println("a student");
  23. System.out.println("a person");
  24. } else if (e instanceof Student) {
  25. System.out.println("a student");
  26. System.out.println("a person");
  27. } else if (e instanceof Person) {
  28. System.out.println("a person");
  29. }
  30. }
  31. public static void main(String[] args) {
  32. InstanceTest i = new InstanceTest();
  33. i.method(new Person());
  34. System.out.println("************************");
  35. i.method(new Student());
  36. System.out.println("************************");
  37. i.method(new Graduate());
  38. }
  39. }
  40. class Person {
  41. protected String name = "person";
  42. protected int age = 50;
  43. public String getInfo() {
  44. return "Name: " + name + "\n" + "age: " + age;
  45. }
  46. }
  47. class Student extends Person {
  48. protected String school = "pku";
  49. public String getInfo() {
  50. return "Name: " + name + "\nage: " + age
  51. + "\nschool: " + school;
  52. }
  53. }
  54. class Graduate extends Student {
  55. public String major = "IT";
  56. public String getInfo() {
  57. return "Name: " + name + "\nage: " + age
  58. + "\nschool: " + school + "\nmajor:" + major;
  59. }
  60. }

4、Object 类的使用

1、Object类是所有Java类的根父类
2、如果在类的声明中未使用extends关键字指明其父类,则默认父类为java.lang.Object类
3、Object类中的功能(属性、方法)就具有通用性
QQ截图20211221153735.png
面试题:==和equals()的区别
一、回顾==的使用
==:运算符
1、可以使用在基本数据类型和引用数据类型变量中
2、如果比较的是基本数据类型变量,比较两个变量保存的数据是否相同(不一定类型相同)
如果比较的是引用数据类型变量,比较两个对象的地址值是否相同。
补充:==符号使用时,必须保证符号左右两边的变量类型一致


二、equals()的使用
1、是一个方法,而非运算符
2、只适用于引用数据类型
3、Object类中equals()的定义
public boolean equals(Object obj) {
return (this == obj);
}
说明:Object中的equals和==的作用是相同的,比较两个对象的地址值是否相同,即两个引用是否指向同一个对象实体
4、当用equals()方法进行比较时,对类File、String、Date及包装类(Wrapper Class)来说,是比较类型及内容而不考虑引用的是否是同一个对象,因为重写了该方法
5、通常情况下,我们自定义类如果使用equals()的话,也通常是比较两个对象的实体内容是否相同,那么,要进行重写
6、对任何不是 null 的对象 x 调用 x.equals(null) 结果都为 false
QQ截图20211221164246.png


Object类中的toString()的使用:
1、当我们输出一个对象的引用时,实际就是调用当前对象的toString()方法
2、Object类中的toString()的定义:
public String toString() {
return getClass().getName() + “@” + Integer.toHexString(hashCode());
}
3、File、String、Date及包装类重写了Object类中的toString()方法,使得在调用对象的toString()时,返回“实体内容”信息。
4、自定义类也可以重写toString()方法,当调用此方法时,返回对象的“实体内容”

Object 通用方法

  1. public final native Class<?> getClass()
  2. public native int hashCode()
  3. public boolean equals(Object obj)
  4. protected native Object clone() throws CloneNotSupportedException
  5. public String toString()
  6. public final native void notify()
  7. public final native void notifyAll()
  8. public final native void wait(long timeout) throws InterruptedException
  9. public final void wait(long timeout, int nanos) throws InterruptedException
  10. public final void wait() throws InterruptedException
  11. protected void finalize() throws Throwable {}

5、包装类(Wrapper)的使用

单元测试
步骤:
1、选中当前工程-右键选择:build path - add libraries -JUnit 4 - 下一步
2、创建java类,进行单元测试
此时的java类要求:①此类是public的②此类提供公共的无参的构造器
3、此类中声明的单元测试方法。
此时的单元测试方法:方法的权限是public,没有返回值,没有形参
4、此单元测试方法上需要声明注解:@Test,并在单元测试类中导入:import org.junit.Test;
5、声明好单元测试方法后,就可以在方法体内测试相关的代码。
6、写完代码后,左键双击单元测试方法名,右键:run as - JUnit Test
说明:
1、如果执行结果没有任何异常:绿条
2、如果执行结果出现任何异常:红条
QQ截图20211222135459.png
包装类的使用:
1、针对八种基本数据类型定义相应的引用类型—包装类(封装类)
2、掌握的:基本数据类型、包装类、String类之间的相互转换
QQ截图20211222140419.png
JDK5.0 新特性:自动装箱和自动拆箱

  1. 如下两个题目输出结果相同吗?各是什么:
  2. Object o1 = true ? new Integer(1) : new Double(2.0);
  3. System.out.println(o1);//1.0
  4. 三元运算符的表达式1和表达式2类型要统一
  5. Object o2;
  6. if (true)
  7. o2 = new Integer(1);
  8. else
  9. o2 = new Double(2.0);
  10. System.out.println(o2);//1
  1. public void method1() {
  2. Integer i = new Integer(1);
  3. Integer j = new Integer(1);
  4. System.out.println(i == j);//false
  5. Integer内部定义了IntegerCache结构,IntegerCache中定义了Integer[],保存了从-128~127范围的整数,
  6. 如果我们使用自动装箱的方式,给Integer赋值的范围在-128~127时,可以直接使用数组中的元素,不用再去new了。
  7. 目的:提高效率
  8. Integer m = 1;
  9. Integer n = 1;
  10. System.out.println(m == n);//true
  11. Integer x = 128;
  12. Integer y = 128;
  13. System.out.println(x == y);//false
  14. }
  1. package com.atguigu.java4;
  2. import java.util.Scanner;
  3. import java.util.Vector;
  4. /**
  5. * 利用Vector代替数组处理:从键盘读入学生成绩(以负数代表输入结束),找出
  6. * 最高分,并输出学生成绩等级。
  7. * 提示:数组一旦创建,长度就固定不变,所以在创建数组前就需要知道它的
  8. * 长度。而向量类java.util.Vector可以根据需要动态伸缩。
  9. * 创建Vector对象:Vector v=new Vector();
  10. * 给向量添加元素:v.addElement(Object obj); //obj必须是对象
  11. * 取出向量中的元素:Object obj=v.elementAt(0);
  12. * 注意第一个元素的下标是0,返回值是Object类型的。
  13. * 计算向量的长度:v.size();
  14. * 若与最高分相差10分内:A等;20分内:B等;30分内:C等;其它:D等
  15. */
  16. public class Test {
  17. public static void main(String[] args) {
  18. Vector v = new Vector();
  19. Scanner sc = new Scanner(System.in);
  20. Double doubleNumber;
  21. int numberStudent = 1;
  22. //将分数存入v中
  23. while (true) {
  24. System.out.print("请输入第" + numberStudent + "个学生的分数: ");
  25. double score = sc.nextDouble();
  26. if (score >= 0) {
  27. doubleNumber = new Double(score);
  28. v.addElement(doubleNumber);
  29. numberStudent++;
  30. } else if (score < 0) {
  31. break;
  32. }
  33. }
  34. //取出元素,并拆箱,赋给定义的double数组
  35. double[] d = new double[v.size()];
  36. for (int i = 0; i < v.size(); i++) {
  37. d[i] = ((Double) v.elementAt(i)).doubleValue();
  38. }
  39. //找出最大值
  40. double max = 0;
  41. for (int i = 0; i < d.length; i++) {
  42. if (max < d[i]) {
  43. max = d[i];
  44. }
  45. }
  46. System.out.println("最大分数为:" + max);
  47. //若与最高分相差10分内:A等;20分内:B等;30分内:C等;其它:D等
  48. for (int i = 0; i < d.length; i++) {
  49. if (max - d[i] <= 10) {
  50. System.out.println(d[i] + ": A");
  51. } else if (max - d[i] <= 20) {
  52. System.out.println(d[i] + ": B");
  53. } else if (max - d[i] <= 30) {
  54. System.out.println(d[i] + ": C");
  55. } else {
  56. System.out.println(d[i] + ": D");
  57. }
  58. }
  59. }
  60. }