Abstract 抽象类

1、抽象类

    在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。

    抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。

    由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类。

    父类包含了子类集合的常见的方法,但是由于父类本身是抽象的,所以不能使用这些方法。

    在 Java 中抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口。

 2、抽象方法

    如果你想设计这样一个类,该类包含一个特别的成员方法,该方法的具体实现由它的子类确定,那么你可以在父类中声明该方法为抽象方法。

    Abstract 关键字同样可以用来声明抽象方法,抽象方法只包含一个方法名,而没有方法体。

    抽象方法没有定义,方法名后面直接跟一个分号,而不是花括号。

  • 如果一个类包含抽象方法,那么该类必须是抽象类。
  • 任何子类必须重写父类的抽象方法,或者声明自身为抽象类。

    继承抽象方法的子类必须重写该方法。否则,该子类也必须声明为抽象类。最终,必须有子类实现该抽象方法,否则,从最初的父类到最终的子类都不能用来实例化对象。

3、代码实例

1、商城模拟Product

(Product类):

package com.ret.demo5;

import java.time.LocalDate;

// 商品类
// 父类
// 抽象类的定义
// abstract抽象类 关键词修饰
public abstract class Product {
	// private修饰的成员变量(方法),子类无法继承(无法访问)
	private double price; // 价格
	private int stock; // 库存

	// 无参构造方法!!!
//	public Product() {
//		
//	}

	// 有参构造方法
	public Product(double price, int stock) {
		this.setPrice(price);
		this.setStock(stock);
	}

	public double getPrice() {
		return 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);
	}

	@Override
	public String toString() {
		String s = String.format("图书商品:<<%s>>,¥%f,作者【%s】,库存%d本", this.bookName, super.getPrice(), this.author,
				super.getStock());
		return s;
	}

	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;
	}

}

调用类(Demo_oop_02):

package com.ret.demo5;

import java.time.LocalDate;

public class Demo_oop_02 {
	public static void main(String[] args) {
		Book book = new Book("红楼梦", "吴承恩", 100, 88);
		desc(book);

		Phone phone = new Phone("Redmi12", 512, 1988, 100);
		desc(phone);

		Food food = new Food("好丽友", 120, LocalDate.now(), 100.5, 10000);
		desc(food);
		
	}

	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());
	}

}

输出结果:

图书名称:<<红楼梦>>
作者姓名:吴承恩
销售价格:¥100.000000
库存数量:88
手机型号:【Redmi12】
内存容量:512GB
销售价格:¥1988.000000
库存数量:100
食品名称:好丽友
食品重量:120kg
保质日期:2024-01-18
销售价格:¥100.500000
库存数量:10000

2、动物模拟Pet

(Pet类):

package com.ret.demo6;

//父类:宠物类
//抽象类的定义
//1.使用abstract关键字定义的类是抽象类
//2.抽象类中允许定义抽象方法
//3.抽象方法使用abstract关键字定义的方法,并且没有方法体
//4.抽象父类中如果存在抽象方法,则子类必须实现该方法
//5.如果有抽象方法但是没有

// 抽象类的使用
// 1.抽象类不允许实例化(不能new对象)
public abstract class Pet {
	// 抽象方法
	public abstract void eat();
}

//子类:猫
class Cat extends Pet{
	//子类必须实现父类Pet的抽象方法eat()
	public void eat() {
		System.out.println("猫吃:鱼、猫条、冻干....");
		
	}
}

//子类:狗
class Dog extends Pet{
	//子类必须实现父类Pet的抽象方法eat()
	public void eat() {
		System.out.println("狗吃:狗粮、骨头、肉....");
	}
}

(调用类Demo_oop_01):

package com.ret.demo6;

public class Demo_oop_01 {
	public static void main(String[] args) {
		// 抽象类不能被实例化
		// Pet p = new Pet()

		Cat c = new Cat();
		Dog d = new Dog();
		Dog x = new Dog();

		ans(c);
		ans(d);
		ans(x);
	}

	// 使用父类作为方法参数类型,可以传入任意一个子类对象
	public static void ans(Pet pet) {
		// 通过父类的引用,调用eat()方法
		// 运行期间,根据pet指向的子类对象,调用不同子类的eat()方法
		pet.eat();

	}
}

输出结果:

猫吃:鱼、猫条、冻干....
狗吃:狗粮、骨头、肉....
狗吃:狗粮、骨头、肉....

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值