知识点1:面向对象的特征之三:多态性
1. 多态性的基本知识点
/* 面向对象的特征之三:多态性
* 1. 多态性:可以理解为一个事物的多种形参。简称:多态性。
*
* 2. 子类对象的多态性:父类的引用指向子类的对象。(或子类的对象赋给父类的引用)
*
* 3. 多态性的应用:虚方法调用(编译看左边,运行看右边)
*
* 4. 多态性的使用前提:① 要有类的继承关系。② 要有方法的重写
*
* 注意:多态性只适用于方法。不适用属性。(编译、运行都看左边)
*/
- 代码演示
package com.atguigu.java;
import javax.sound.midi.Soundbank;
public class Person {
String name;
int age;
int id = 1001;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person() {
}
public void eat(){
System.out.println("人吃饭");
}
public void walk(){
System.out.println("人走路");
}
}
package com.atguigu.java;
public class Man extends Person {
boolean isSmoking;
int id = 1002;
public Man(String name, int age, boolean isSmoking) {
super(name, age);
this.isSmoking = isSmoking;
}
public Man() {
}
@Override
public void eat() {
System.out.println("男人应该多吃肉,长肌肉");
}
@Override
public void walk() {
System.out.println("奔跑吧!兄弟~~");
}
public void earnMoney(){
System.out.println("男人赚钱养家~~");
}
}
package com.atguigu.java;
public class Woman extends Person {
boolean isBeauty;
public Woman(String name, int age, boolean isBeauty) {
super(name, age);
this.isBeauty = isBeauty;
}
public Woman() {
}
@Override
public void eat() {
System.out.println("女人少吃饭,减肥~~~");
}
@Override
public void walk() {
System.out.println("女人窈窕的走路");
}
public void goShopping(){
System.out.println("女人心情不好时,多逛逛街~~");
}
}
public class PersonTest {
public static void main(String[] args) {
//多态之前:
Person p1 = new Person();
p1.eat();
Man m1 = new Man();
m1.eat();
m1.earnMoney();
//使用多态:父类的引用指向子类的对象。(或子类的对象赋给父类的引用)
Person p2 = new Man();
Person p3 = new Woman();
//多态的使用:虚方法调用(virtual method)
//编译时,只能调用父类中声明过的方法。(编译看左边)
//运行时,真正执行的是子类重写父类的方法。(运行看右边)
p2.eat();//男人应该多吃肉,长肌肉
// p2.earnMoney();//编译不通过
System.out.println(p2.id);//1001
}
}
2. 多态性的应用举例(why?)
package com.atguigu.java1;
/**
*
* 多态性使用的举例:为什么要有多态性
*/
public class AnimalTest {
public static void main(String[] args) {
AnimalTest test = new AnimalTest();
test.func(new Dog());
test.func(new Cat());
}
public void func(Animal animal){//Animal animal = new Dog()
animal.eat();
animal.shout();
// animal.protectHome();
if(animal instanceof Dog){
Dog dog = (Dog)animal;
dog.protectHome();
}else if(animal instanceof Cat){
Cat cat = (Cat)animal;
cat.catchMouse();
}
}
// public void func(Dog dog){
// dog.eat();
// dog.shout();
// }
//
// public void func(Cat cat){
// cat.eat();
// cat.shout();
// }
}
class Animal{
public void shout(){
System.out.println("动物叫~~");
}
public void eat(){
System.out.println("动物进食~~");
}
}
class Dog extends Animal{
public void shout(){
System.out.println("汪~汪~汪~");
}
public void eat(){
System.out.println("狗吃骨头~~");
}
public void protectHome(){
System.out.println("狗看家");
}
}
class Cat extends Animal{
public void shout(){
System.out.println("喵~喵~喵~");
}
public void eat(){
System.out.println("猫吃鱼~~");
}
public void catchMouse(){
System.out.println("猫抓老鼠");
}
}
/*
举例二
class Account{
double balance;
public void withdraw(double amt){}
public void deposit(double amt){}
}
class CheckAccount extends Account{//信用卡
double overdraft;
public void withdraw(double amt){}
}
class SavingAccount extends Account{}//储蓄卡
class Customer{
Account acct;
public void setAccount(Account acct){ //Account acct = new CheckAccount();
this.acct = acct;
}
}
*/
/*
举例三
数据库:mysql 、 oracle 、 sqlsever 、 db2
class DataOperate{
public void addData(Connection conn,Statement st){ //
conn.do();
st.execute();
}
}
*/
3. 向下转型
Person p4 = new Man();
// p4.earnMoney();
// System.out.println(p4.isSmoking);
//向下转型:多态的逆过程。将父类的引用转为子类的引用
//需要使用强转符:()
Man m2 = (Man)p4;
System.out.println(m2.isSmoking);
m2.earnMoney();
//ClassCastException:类型转换异常
// Woman w1 = (Woman)p4;
// System.out.println(w1.isBeauty);
// w1.goShopping();
/*
instanceof的使用:
1) a instanceof A:判断对象a是否是类型A的实例。如果是,返回true。否则,返回false.
2) 如果a instanceof A返回true,则a instanceof SuperA也一定返回true.
其中,SuperA是A的父类。
*/
if(p4 instanceof Woman){
Woman w1 = (Woman)p4;
System.out.println(w1.isBeauty);
w1.goShopping();
}else{
System.out.println("p4不是一个Woman的实例");
}
if(p4 instanceof Man){
Man m3 = (Man)p4;
System.out.println("我是一个Man");
}
if(p4 instanceof Person){
System.out.println("我是一个Person");
}
知识点2:Object类的使用
1. equals(Object obj)的使用
package com.atguigu.java2;
import java.io.File;
/**
*
* 测试Object类中equals()的使用
*
* 1. java.lang.Object类中equals()的定义如下:
* public boolean equals(Object obj) {
* return (this == obj);
* }
* 2. 像String\包装类\File类等,都重写了Object类中的equals()。用于比较两个对象的内容是否相等。
*
* 3. 对于自定义来讲,如果没有重写Object类中的equals()。当调用equals()方法时,仍然比较的是两个
* 对象的地址值是否相同。(或两个对象引用是否指向了堆空间中的同一个对象)
*
* 如果重写,则重写的规则:比较两个对象的实体内容是否相同。(即:对象的属性是否相同)
*
* 4. 面试题:区分 == 和 equals()
* == : 适用范围:基本数据类型、引用数据类型
* equals():适用范围:引用数据类型
*
*/
public class EqualsTest {
public static void main(String[] args) {
// String str1 = "hello";
String str2 = new String("hello");
String str3 = new String("hello");
System.out.println(str2 == str3);//false
System.out.println(str2.equals(str3));//true
File file1 = new File("d:\\io\\hello.txt");
File file2 = new File("d:\\io\\hello.txt");
System.out.println(file1.equals(file2));
//##############################
Order order1 = new Order(1001,"AA");
Order order2 = new Order(1001,"AA");
System.out.println(order1 == order2);//false
System.out.println(order1.equals(order2));//false ---> true
System.out.println("#####################");
SubOrder order3 = new SubOrder(1001,"AA");
System.out.println(order1.equals(order3));
System.out.println("#####################");
int m = 10;
int n = 10;
System.out.println(m == n);//true
float f = 10.0F;
System.out.println(f == n);//true
char c = 'A';
int k = 65;
System.out.println(c == k);//true
}
}
- 对应的Order类如下:
package com.atguigu.java2;
import java.util.Objects;
/**
* @author shkstart
* @create 2020-08-04 14:25
*/
public class Order {
private int orderId;
private String orderName;
public int getOrderId() {
return orderId;
}
public void setOrderId(int orderId) {
this.orderId = orderId;
}
public String getOrderName() {
return orderName;
}
public void setOrderName(String orderName) {
this.orderName = orderName;
}
public Order(int orderId, String orderName) {
this.orderId = orderId;
this.orderName = orderName;
}
public Order() {
}
//重写Object类的equals()
//手动定义了equals()
// public boolean equals(Object obj) {
// System.out.println("Order equals()...");
// if(this == obj){
// return true;
// }
//
// if(obj instanceof Order){
// Order order = (Order)obj;
//
if(this.orderId == order.orderId && this.orderName.equals(order.orderName)){
return true;
}else{
return false;
}
// //或
// return this.orderId == order.orderId && this.orderName.equals(order.orderName);
// }
//
// return false;
//
// }
//自动生成equals()
// @Override
// public boolean equals(Object o) {
// if (this == o) return true;
// if (!(o instanceof Order)) return false;
//
// Order order = (Order) o;
//
// if (orderId != order.orderId) return false;
// return orderName != null ? orderName.equals(order.orderName) : order.orderName == null;
// }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Order order = (Order) o;
if (orderId != order.orderId) return false;
return orderName != null ? orderName.equals(order.orderName) : order.orderName == null;
}
//重写Object类的toString()
//手动生成的:
// public String toString() {
// return "Order[orderId = " + orderId + ", orderName = " + orderName + "]";
// }
}
2. toString()的使用
/**
*
* 1.java.lang.Object类中toString()的定义:
* public String toString() {
* return getClass().getName() + "@" + Integer.toHexString(hashCode());
* }
* 说明:当我们打印对象的引用时,实际上就是调用当前对象的toString()
*
* 2. 像String、包装类、File类等都重写了Object类中的toString(),用于输出当前对象的实体内容
*
* 3. 如果自定义类没有重写toString()时,默认返回当前对象所属的类及对象的地址值。如果我们重写的话,
* 则规则为:返回当前对象的各个属性值。
*
*
*/
public class toStringTest {
public static void main(String[] args) {
Order order1 = new Order(1001,"AA");
System.out.println(order1.toString());//com.atguigu.java2.Order@1540e19d -->Order[orderId = 1001, orderName = AA]
System.out.println(order1);//com.atguigu.java2.Order@1540e19d -->Order[orderId = 1001, orderName = AA]
String str = new String("hello");
System.out.println(str.toString());
File file1 = new File("d:\\io\\hello.txt");
System.out.println(file1.toString());
}
}
- 对应的Order类如下:
package com.atguigu.java2;
import java.util.Objects;
/**
*/
public class Order {
private int orderId;
private String orderName;
public int getOrderId() {
return orderId;
}
public void setOrderId(int orderId) {
this.orderId = orderId;
}
public String getOrderName() {
return orderName;
}
public void setOrderName(String orderName) {
this.orderName = orderName;
}
public Order(int orderId, String orderName) {
this.orderId = orderId;
this.orderName = orderName;
}
public Order() {
}
@Override
public String toString() {
return "Order{" +
"orderId=" + orderId +
", orderName='" + orderName + '\'' +
'}';
}
}
知识点3:JUnit单元测试类的使用
package com.atguigu.java3;
import org.junit.Test;
/**
*
* 单元测试方法:
* 一、添加jar包方式
* 1.在当前module下-new - directory。命名为:lib
* 2.将 junit-4.12.jar和hamcrest-core-1.3.jar包复制到lib目录下
* 3. 选中两个jar包,右键 add as library - 选择当前的module
*
* 二、创建单元测试类和方法
* 1. 单元测试类要求:① 单元测试类是public的 ,并提供public权限的空参的构造器
* 2. 创建单元测试方法
* 要求:① 单元测试方法前声明有:@Test。 导包为: import org.junit.Test;
* ② 单元测试方法必须是public的、void的、没有形参的方法
*
* 3. 在单元测试方法内可以定义变量、调用本类中的一般方法。
*
*/
public class JUnitTest {
@Test
public void test1(){
System.out.println("hello");
int m = 10;
int n = 20;
System.out.println(m + n);
}
@Test
public void test2(){
System.out.println("hello,上海!");
show("应该会比较凉快~");
}
public void show(String info){
System.out.println("据说今晚有台风登陆。。。。");
System.out.println(info);
}
}
- 图示:
知识点4:包装类的使用
-
为什么要有包装类
-
掌握:基本数据类型、包装类、String三者之间的转换
-
复杂的转换图:(不要记忆)
-
简图:
public class WrapperTest {
// public static void main(String[] args) {
// System.out.println("hello");
// }
/*
基本数据类型 ---> 包装类:
包装类 ---> 基本数据类型:
*/
@Test
public void test1(){
int num1 = 10;
// 基本数据类型 ---> 包装类:使用包装类的构造器
Integer i1 = new Integer(num1);
System.out.println(i1.toString());
float f1 = 12.3F;
Float f2 = new Float(f1);
System.out.println(f2.toString());
boolean b1 = false;
Boolean b2 = new Boolean(b1);
//包装类 ---> 基本数据类型:调用包装类Xxx的xxxValue()
Integer i2 = new Integer(20);
int int1 = i1.intValue();
int int2 = i2.intValue();
System.out.println(int1 + int2);
boolean b3 = b2.booleanValue();
}
/*
jdk5.0 中关于基本数据类型与包装类转化时,提供了新特性:自动装箱、自动拆箱
*/
@Test
public void test2(){
int i1 = 10;
Integer i2 = i1;//自动装箱
System.out.println(i2.toString());
int i3 = i2;//自动拆箱
System.out.println(i3);
Float f1 = 12.3F;//自动装箱
Float f2 = 12.4F;//自动装箱
float f3 = f1 - f2;//自动拆箱
System.out.println(f3);
}
/*
基本数据类型、包装类 ---> String : 1.使用连接符 2.调用String重载的valueOf(xxx xxx)
String---> 基本数据类型、包装类:调用包装类Xxx的parseXxx(String s)方法
*/
@Test
public void test3(){
int i1 = 10;
Integer i2 = 10;
//1.使用连接符
String s1 = i1 + "";
String s2 = i2 + "";
//2.调用String重载的valueOf(xxx xxx)
String s3 = String.valueOf(i1);
//
String s4 = "123";
// s4 = "123a";//java.lang.NumberFormatException: For input string: "123a"
int i3 = Integer.parseInt(s4);
System.out.println(i3 + 0);
String s5 = "123.1";
double d1 = Double.parseDouble(s5);
System.out.println(d1);
String s6 = "true1";
s6 = "TrUe";
boolean b1 = Boolean.parseBoolean(s6);
System.out.println(b1);
}
}