思考: 构造方法能作为抽象方法吗?
“去商场买衣服”,这句话描述的是一个抽象的行为∶到底去哪个商场买衣服,是实体店还是网店,买什么样的衣服,是短衫、裙子,还是其他的什么衣服?在"去商场买衣服"这句话中,并没有为"买衣服"这个抽象行为指明一个确定的信息。设计一个商场的抽象类,并在其中定义买东西的抽象方法,具体是什么商场、买什么东西,交给子类去实现即可。代码如下∶
public abstract class Market {
public String name; // 商场名称
public String goods; // 商品名称
public abstract void shop(); // 抽象方法,用来输出信息
}
定义一个TaobaoMarket类,继承自 Market 抽象类,实现其中的shop()抽象方法:
public class TaobaoMarket extends Market {
public void shop() {
System.out.println(name + "网购" + goods);
}
}
定义一个 WallMarket 类,继承自Market 抽象类,实现其中的shop()抽象方法:
public class WallMarket extends Market {
public void shop() {
System.out.println(name + "实体店购买" + goods);
}
}
定义一个 GoShopping类,在该类中分别使用WallMarket类和TaobaoMarket类创建抽象类的对象,并分别给抽象类中的成员变量赋不同的值,调用 shop()方法分别输出结果:
public class GoShopping {
public static void main(String[] args) {
Market market = new WallMarket(); // 使用派生类对象创建抽象类对象
market.name = "沃尔玛";
market.goods = "七匹狼西服";
market.shop();
market = new TaobaoMarket(); // 使用派生类对象创建抽象类对象
market.name = "淘宝";
market.goods = "韩都衣舍花裙";
market.shop();
}
}
创建 Shape(图形)类,该类中有一个计算面积的方法。圆形和矩形都继承自图形类,输出圆形和矩形的面积。
public class Circle extends Shape {
double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public double getArea() {
return Math.PI * this.radius * this.radius;
}
}
public class Rectangle extends Shape {
double length;
double width;
public Rectangle(double length, double width) {
this.length = length;
this.width = width;
}
@Override
public double getArea() {
return this.length * this.width;
}
}
public abstract class Shape {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract double getArea();
}
public class Test {
public static void main(String[] args) {
Circle circle = new Circle(1.5);
circle.name = "圆形";
System.out.println(circle.name + "面积:" + circle.getArea());
Rectangle rectangle = new Rectangle(5.5, 2);
rectangle.name = "矩形";
System.out.println(rectangle.name + "面积:" + rectangle.getArea());
}
}
创建工厂类,工厂类中有一个抽象的生产方法,创建汽车厂和鞋厂类,重写工厂类中的抽象生产方法,输出汽车厂生产的是汽车,鞋厂生产的是鞋。
public class AutoPlant extends Factory {
String productsName;
public AutoPlant(String productsName) {
this.productsName = productsName;
}
@Override
public String produce() {
return this.productsName;
}
}
public abstract class Factory {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract String produce();
}
public class ShoeFactory extends Factory {
String productsName;
public ShoeFactory(String productsName) {
this.productsName = productsName;
}
@Override
public String produce() {
return this.productsName;
}
}
public class Test {
public static void main(String[] args) {
AutoPlant autoPlant = new AutoPlant("汽车");
autoPlant.setName("汽车厂");
System.out.println(autoPlant.getName() + "生产的是" + autoPlant.productsName);
ShoeFactory shoeFactory = new ShoeFactory("鞋");
shoeFactory.setName("鞋厂");
System.out.println(shoeFactory.getName() + "生产的是" + shoeFactory.productsName);
}
}
使用抽象类和抽象方法时,需要遵循以下原则∶
特殊的平行四边形有矩形、正方形和菱形。现使用接口的相关知识绘制出特殊的平行四边形。
interface DrawImage { // 定义“画图形”接口
public void draw(); // 定义抽象方法“画”
}
class Rectangle implements DrawImage { // 矩形类实现了drawTest接口
public void draw() { // 矩形类中实现draw()方法
System.out.println("画矩形");
}
}
class Square implements DrawImage { // 正方形类实现了drawTest接口
public void draw() { // 正方形类中实现draw()方法
System.out.println("画正方形");
}
}
class Diamond implements DrawImage { // 菱形类实现了drawTest接口
public void draw() { // 菱形类中实现draw()方法
System.out.println("画菱形");
}
}
public class SpecialParallelogram { // 定义特殊的平行四边形类
public static void main(String[] args) {
// 接口也可以进行向上转型操作
DrawImage[] images = { new Rectangle(), new Square(), new Diamond() };
// 遍历“画图形”接口类型的数组
for (int i = 0; i < images.length; i++) {
images[i].draw(); // 调用draw()方法
}
}
}
提醒: 由于接口中的方法都是抽象方法,所以当子类实现接口时,必须实现接口中的所有抽象方法。
爸爸喜欢做的事有抽烟和钓鱼,妈妈喜欢做的事有看电视和做饭,儿子完全继承了爸爸妈妈的爱好,使用多重继承输出儿子喜欢做的事。首先定义一个DadLikeDo接口,并在接口中定义两个方法 smoke()和 fish():
public interface DadLikeDo { // 定义“爸爸喜欢做的事”接口
void smoke(); // 抽烟的方法
void fish(); // 钓鱼的方法
}
public interface MomLikeDo { // 定义“妈妈喜欢做的事”接口
void watchTV(); // 看电视的方法
void cook(); // 做饭的方法
}
// 继承DadLikeDo接口和MomLikeDo接口
public class SonLikeDo implements DadLikeDo, MomLikeDo {
public void watchTV() { // 实现watchTV()方法
System.out.println("看电视");
}
public void cook() { // 实现cook()方法
System.out.println("做饭");
}
public void smoke() { // 实现smoke()方法
System.out.println("抽烟");
}
public void fish() { // 实现fish()方法
System.out.println("钓鱼");
}
public static void main(String[] args) {
SonLikeDo son = new SonLikeDo(); // 通过子类创建IFather接口对象
System.out.println("儿子喜欢做的事有:");
// 子类对象调用DadLikeDo和MomLikeDo两个接口被实现的所有方法
son.watchTV();
son.cook();
son.smoke();
son.fish();
}
}
思考:
如何区分抽象类和接口?有哪些不同?