JavaSE 第二十一讲:多态详解 续2

1.抽象类(abstract class):使用了abstract关键字所修饰的类叫做抽象类。抽象类无法实例化,也就是说,不能new出来一个抽象类的对象(实例)。

抽象类的定义格式:

public abstract class abstractTest
{
}

public class Test
{
	public static void main(String[] args)
	{
		T t = new T();
	}
}

abstract class T
{

}
执行结果:

D:\src>javac Test.java
Test.java:5: 错误: T是抽象的; 无法实例化
                T t = new T();
                      ^
1 个错误

【说明】:以上程序错误的原因是抽象类不能被实例化


2.抽象方法(abstract method):使用abstract关键字所修饰的方法叫做抽象方法(有声明,无实现)。抽象方法需要定义在抽象类中。相对于抽象方法,之前所定义的方法叫做具体方法(有声明,实现)。

public class Test
{
	public static void main(String[] args)
	{
	}
}

abstract class T
{
	public abstract void method();
}
上例程序中定义一个抽象方法:public abstract void method();注意直接用分号结束,没有花括号,没有花括号表示没有实现这个方法,注意的是如果有花括号即便是花括号里面没有内容,这也算是有实现的,只不过这个方法体为空,空实现。

3.如果一个类包含了抽象方法,那么这个类一定是抽象类。

4.如果某个类是抽象类,那么该类可以包含具体方法(有声明,有实现)。

public class Test
{
	public static void main(String[] args)
	{
	}
}

abstract class T
{
	public abstract void method();
	public void test()
	{
		System.out.println("test");
	}
}
编译成功!


5.如果一个类中包含了抽象方法,那么这个类一定要声明成abstract class,也就是说,该类一定是抽象类;反之,如果某个类是抽象类,那么该类既可以包含抽象方法,也可以包含具体方法,甚至什么都不包含也是可以的。


6.无论何种情况,只要一个类是抽象类,那么这个类就无法实例化。


7.在子类继承父类(父类是个抽象类)的情况下,那么该子类必须要实现父类中所定义的所有抽象方法;如果子类不实现父类的所有方法,否则,该子类需要声明成一个abstract class

public class Test
{
	public static void main(String[] args)
	{
		R r = new R();
	}
}

abstract class T
{
	public abstract void method();
	public void test()
	{
		System.out.println("test");
	}
}

class R extends T
{

}
编译结果:

D:\src>javac Test.java
Test.java:18: 错误: R不是抽象的, 并且未覆盖T中的抽象方法method()
class R extends T
^
1 个错误


两种解决办法:

第一种实现父类的抽象方法:

public class Test
{
	public static void main(String[] args)
	{
		R r = new R();
	}
}

abstract class T
{
	public abstract void method();
	public void test()
	{
		System.out.println("test");
	}
}

class R extends T
{
	public void method()
	{
		System.out.println("method");
	}

}
编译通过!


第二种,将子类转为抽象类

public class Test
{
	public static void main(String[] args)
	{
	//	R r = new R();
	}
}

abstract class T
{
	public abstract void method();
	public void test()
	{
		System.out.println("test");
	}
}

abstract class R extends T
{

}
编译通过!

【说明】:此时子类还是不能被实例化,如果想使用这个子类,还必须定义一个R的一个子类,把method的方法实现出来。


继续修改以上例子:

public class Test
{
	public static void main(String[] args)
	{
	//	R r = new R();
	}
}

abstract class T
{
	public abstract void method();
	public void test()
	{
		System.out.println("test");
	}
}

abstract class R extends T
{
	public void method()
	{
		System.out.println("method");
	}
}
编译成功!

【说明】:R继承了T,则R类里面有两个方法,一个方法是实现T的抽象方法,另外一个是从T当中继承下来的具体方法test();此时把R声明为抽象类正常,应该抽象类本身可以包含具体方法,也可以包含抽象方法。


8.抽象方法,抽象类有什么作用,有声明没实现?
这个实现是推迟到子类当中去实现的,父类实现不了,父类可以声明一个抽象方法,写一个注释,告诉这个类的实现者,告诉它我这个方法有什么用,可以让子类去实现,对于一个父类来说,可以有多个子类,而不同的子类可以实现不同的方法。比如说在父类中定义一个排序的抽象方法,而在这个父类的各个子类当中可以分别实现这个抽象方法,具体子类实现方法有可能是用冒泡排序,有可能是用哈希排序,每种实现规则的不一样,从这一点可以看出,抽象类和抽象方法主要起到一个规范,约束的作用。

举个例子加深理解

public class Test2
{
	public static void main(String[] args)
	{
		Shape shape = new Triangle(10,6);
		int area = shape.computerArea();
		System.out.println("triangle:" + area);
		
		shape = new Rectangle(10,10); //前面area用完,shape指向完已经关闭,下面可以不用定义直接使用。     
		area = shape.computerArea();
	        System.out.println("rectangle" + area);	
	}

}

abstract class Shape
{
	public abstract int computerArea(); //计算形状面积
}

class Triangle extends Shape
{
	int width;
	int height;
	public Triangle(int width, int height)  //用构造方法来完成一些初始化工作
	{
		//注意此处用this是因为生命完构造方法之后,把方法外面的int width;和int height;给屏蔽掉了,所以这个地方要访问到外面的width和height成员变量就用this,this表示对自己的引用。这样就把方法参数传给成员变量。
		this.width = width;     
		this.height = height;
	}

	public int computerArea()
	{
		return width * height / 2;
	}
}

class Rectangle extends Shape
{
	int width;
	int height;
	public Rectangle(int width,int height)
	{
		this.width = width;
		this.height = height;
	}
	public int computerArea()
	{
		return width * height;
	}
}
执行结果:

D:\src>java Test2
triangle:30
rectangle100

【说明】:从这个例子说可以看到抽象方法起到规范,规则子类行为的作用具体怎么实现满足这个规则由子类去实现。约束规则,比如说定义什么类型,传递什么参数等。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值