我们先准备一个Product商品类,和一个Text类。
Product商品类:
package com.zad.day24_1_18_01;
import java.time.LocalDate;
// 商品类
// 父类
public abstract class Product {
// private修饰的成员变量(方法),子类无法继承(无法访问)
private double price; // 价格
private int stock; // 库存
// // 无参构造方法!!!
// public Product() {
//
// }
// 有参构造方法
public Product(double price,int stock) {
this.setPrice(price); //调用setPrice方法
this.setStock(stock);
}
//为了保证数据的安全性,会把数据定义为private,如果想要调用就会用到set、get方法
public double getPrice() {
return price;
}
//将price存储在当前类的成员变量中
public void setPrice(double price) {
if(price <= 0) {
this.price = 0.01;
}else {
this.price = price;
}
}
public int getStock() {
return stock;
}
public void setStock(int stock) {
this.stock = stock;
}
}
// 图书类
// 子类
class Book extends Product{
//子类成员变量
private String bookName; // 图书名称
private String author; // 作者姓名
//子类的有参构造方法
public Book(String bookName,String author,double price,int stock) {
//调用父类的构造方法
super(price,stock);
// 直接保存至"图书类"的成员变量中
this.bookName = bookName;
this.author = author;
// 通过父类的set方法,将价格和库存,保存至父类的成员变量
// this.setPrice(price);
// this.setStock(stock);
// super关键字代表父类对象
// super.setPrice(price);
// super.setStock(stock);
}
//重写toString()方法
@Override
public String toString() {
String s = String.format("图书商品:<<%s>>,¥%f,作者【%s】,库存%d本",
this.bookName,super.getPrice(),
this.author,super.getStock());
return s;
}
//book类的get和set方法
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
// 手机类
// 子类
class Phone extends Product{
private String model;
private int memory;
public Phone(String model,int memory,double price,int stock) {
// 通过父类的set方法,保存价格和库存
// super.setPrice(price);
// super.setStock(stock);
// 通过父类的有参构造方法,保存价格和库存
super(price,stock);
// 型号和内存
this.model = model;
this.memory = memory;
}
@Override
public String toString() {
String s = String.format("手机商品:【%s】,¥%f,内存%dG,库存%d部",
this.model,super.getPrice(),
this.memory,super.getStock());
return s;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public int getMemory() {
return memory;
}
public void setMemory(int memory) {
this.memory = memory;
}
}
// 食品类
class Food extends Product{
private String foodName;
private int weight;
private LocalDate date;
public Food(String foodName,int weight,LocalDate date,double price,int stock) {
super(price,stock);
this.foodName = foodName;
this.weight = weight;
this.date = date;
}
public String getFoodName() {
return foodName;
}
public void setFoodName(String foodName) {
this.foodName = foodName;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public LocalDate getDate() {
return date;
}
public void setDate(LocalDate date) {
this.date = date;
}
}
Text测试类:
package com.zad.day24_1_18_01;
import java.time.LocalDate;
public class Text02 {
public static void main(String[] args) {
//创建对象x,并且调用Book类的有参构造方法
Book x = new Book("红与黑","司汤达",51.6,12345);
//创建对象x,并且调用Phone类的有参构造方法
Phone p = new Phone("RedMi12",512,1988,100);
//创建对象f,并且调用Food类的有参构造方法
Food f = new Food("好丽友",100,LocalDate.now(),100.5,1000);
desc(x);
desc(p);
desc(f);
}
//desc()方法的重载
public static void desc(Phone phone) {
System.out.printf("手机型号:【%s】\n",phone.getModel());
System.out.printf("内存容量:%dGB\n",phone.getMemory());
System.out.printf("销售价格:¥%f\n",phone.getPrice());
System.out.printf("库存数量:%d个\n",phone.getStock());
}
public static void desc(Book book) {
System.out.printf("图书名称:《%s》\n",book.getBookName());
System.out.printf("作者姓名:%s\n",book.getAuthor());
System.out.printf("销售价格:¥%f\n",book.getPrice());
System.out.printf("库存数量:%d个\n",book.getStock());
}
public static void desc(Food food) {
System.out.printf("食品名称:%s\n",food.getFoodName());
System.out.printf("食品重量:%dkg\n",food.getWeight());
System.out.printf("保质日期:%s\n",food.getDate());
System.out.printf("销售价格:¥%f\n",food.getPrice());
System.out.printf("库存数量:%d个\n",food.getStock());
}
}
输出为:
图书名称:《红与黑》
作者姓名:司汤达
销售价格:¥51.600000
库存数量:12345个
手机型号:【RedMi12】
内存容量:512GB
销售价格:¥1988.000000
库存数量:100个
食品名称:好丽友
食品重量:100kg
保质日期:2024-01-19
销售价格:¥100.500000
库存数量:1000个
通过以上测试,我们可以发现:在进行desc()方法的重载时,重复的去调用父类的get方法进行输出,略显累赘,我们可以通过向上转型和向下转型来优化此代码。如下:
Text类:
package com.zad.day24_1_18_01;
import java.time.LocalDate;
public class Text02 {
public static void main(String[] args) {
Product x = new Book("红与黑","司汤达",51.6,12345);
Product p = new Phone("RedMi12",512,1988,100);
Product f = new Food("好丽友",100,LocalDate.now(),100.5,1000);
desc(x);//传参时,发生向上转型
desc(p);//传参时,发生向上转型
desc(f);//传参时,发生向上转型
}
public static void desc(Product p) {
if(p instanceof Book) {
Book book = (Book)p;//向下转型
System.out.printf("图书名称:《%s》\n",book.getBookName());
System.out.printf("作者姓名:%s\n",book.getAuthor());
}else if(p instanceof Phone) {
Phone phone = (Phone)p;//向下转型
System.out.printf("手机型号:【%s】\n",phone.getModel());
System.out.printf("内存容量:%dGB\n",phone.getMemory());
}else if(p instanceof Food) {
Food food = (Food)p;//向下转型
System.out.printf("食品名称:%s\n",food.getFoodName());
System.out.printf("食品重量:%dkg\n",food.getWeight());
System.out.printf("保质日期:%s\n",food.getDate());
}
System.out.printf("销售价格:¥%f\n",p.getPrice());
System.out.printf("库存数量:%d个\n",p.getStock());
}
}
输出为:
图书名称:《红与黑》
作者姓名:司汤达
销售价格:¥51.600000
库存数量:12345个
手机型号:【RedMi12】
内存容量:512GB
销售价格:¥1988.000000
库存数量:100个
食品名称:好丽友
食品重量:100kg
保质日期:2024-01-19
销售价格:¥100.500000
库存数量:1000个
在进行向上转型的时候,子类可以用父类的方法,但是就不能再去调用自己的方法,所以调用完父类的方法之后,再进行向下转型,从而调用自己的方法。这样就可以优化代码,使其更加简洁。