抽象类
一、抽象
面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的。 如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
例如:动物,植物,星球等抽象概念
语法格式:在不同类的定义前面加上一个 abstract ,就表示抽象类。
例如:
abstract class Tree
{
···················
}
抽象类的主要目的:该类不能完整的描述对象,所以不允许创建对象,必须强制该类被继承后,才可以使用。
注意:final和abstract是不能同时修饰的;
【抽象类仍然是一个类,除了不能直接实例化之外,与普通的类基本一致,它使用关键字abstract来对一个类进行修饰】
abstract:只能修饰类和方法
修饰类:表示该类是一个抽象类,必须被继承
修饰方法:如果修饰方法则该方法必须被重写,如果一个类中有一个以上的抽象方法, 则该类必须为抽象类。
使用abstract修饰的方法,只有方法的名称没有方法体。
【抽象类不一定是有抽象方法,但是抽象方法的类必须是抽象类】
抽象类:是把相同功能的信息抽取出来,并作为一个类的继承模板。它本身是一个类,具有除创建对象外的所以类的功能。
例:
通过抽象类求得长方形和圆的周长面积
public class NEW {
public static void main(String[] args) {
// TODO Auto-generated method stub
Shape a=new Rect(10,20);//建立Rect类对象a
a.getarea();//得出面积
a.getlen();//得出周长
Shape b=new Circle(3);//建立子类Circle的对象b
b.getarea();//得出面积
b.getlen();//得出周长
}
}
abstract class Shape{//建立父类为抽象类
abstract double getlen();//周长
abstract double getarea();//面积
}
class Rect extends Shape{//子类Rect继承父类
double length;//长
double width;//宽
public Rect(double length,double width) {
this.length=length;
this.width=width;
}
@Override //重写
double getlen() {
// TODO Auto-generated method stub
System.out.println((length+width)*2);
return (length+width)*2;
}
@Override
double getarea() {
// TODO Auto-generated method stub
System.out.println(length*width);
return length*width;
}
}
class Circle extends Shape{//子类Circle继承父类
double rid;//半径
double pi=3.14;
public Circle(double rid) {
this.rid=rid;
}
@Override
double getlen() {
// TODO Auto-generated method stub
System.out.println(2*pi*rid);
return 2*pi*rid;
}
@Override
double getarea() {
// TODO Auto-generated method stub
System.out.println(rid*rid*pi);
return rid*rid*pi;
}
运行结果如下所示:
二 、
接口: 接口它是一个特殊的抽象类(只包含抽象方法和常量),它主要描述的是一种功能的集合。它本身不是类。你可以创建接口的变量,不能创建接口的对象。
【面向接口编程,其他的:面向过程,面向对象,面向切面】
接口的语法:
[public] interface interfaceName [extends SuperInterfaceList] {
常量属性
抽象方法
}
接口里面的属性是:public static final int a; 但是可以省略public static final,默认就是这个类型
方法:默认是public abstract;
public default void getcolor(){
System.out.println(“打印颜色”);
}
【类可以实现多个接口,接口之间使用逗号分隔,1个类即可以继承类,也可以实现接口,但是必须先继承类,后实现接口。】
如:class XXX (子类名) implements YYY(接口类名){}
注意:java只支持单继承,但是要考虑接口的多继承。
一个类可以实现一个接口,如果未能全部实现接口方法,则该类为抽象类,换句话说,抽象类是可以实现接口的。
总结:
1、接口没有构造方法。
2、接口中定义的所有属性默认是public static final的,即静态常量。
3、接口中定义的所有方法默认是public abstract的,即抽象方法。
4、由于接口中的定义的所有方法默认都是抽象的,所以接口不能被实例化。
5、有抽象函数的不一定是抽象类,也可以是接口。
6、类可以通过implements实现接口,一个类可以实现多个接口。
7、如果类没有实现接口中的所有方法,那么类必须是抽象类。
8、如果在类中访问接口中的属性,不能使用super关键字,因为两者之间没有显示的继 承关系。
interface JieKou{//创建接口
public String shuchu();
}
class XiFen implements JieKou{//利用接口
public XiFen() {//默认构造方法
}
@Override
public String shuchu() {
System.out.println("输出");
return "输出";
}多态
1.概念:事物存在的多重形态,即同一种事物由于条件不同,产生的结果也不同。多态只发生于继承关系,可以理解为父类变量可以指向子类对象。
2.方法:实现多态的技术:动态绑定(dynamic binding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。【重写才可以动态绑定】
3.条件:多态存在的三个必要条件:
1)要有继承关系或者要有接口的实现关系
2)要有方法重写
3) 要有父类引用指向子类对象(格式:Father fa = new Son())
4.多态具有的特点
1) 多态中成员访问成员变量的特点: 多态对成员变量的访问时不构成多态特性的(如在父类中int number=111,子类中创建 int number=222。主函数在输出子类中的number时,结果仍然是父类中number的值)
2)多态中成员方法的访问特点:对重写过的成员方法有效
父类变量指向子类对象,在通过父类变量调用子类对象的重写方法时,则调用的实际方法时子类的重写方法。否则不是重写方法则调用自己的。
5.多态的用处:
1) 可以使用父类接受该父类下的所有对象。特殊情况为:Object 的变量可以接受java中的任意类型。
2) 可以使用该变量调用子类的重写方法时,达到方法的特殊调用会根据你传递的对象不同而动态变化。
3)多态中访问静态成员的特点:多态其实仅限于类的非静态成员方法,只有在运行时才能决定具体调用谁。
注:此处代码引用他人
package cn.com;
public class TestPolymorphism {
public static void main(String[] args) {
// TODO Auto-generated method stub
TwoDragonM t=new TwoDragonM();
t.trueWords();
System.out.println("--------");
Wine w1=new TwoDragonM();
w1.trueWords();
int num = w1.number;
System.out.println("num="+num);
Wine w2=new FenWine();
w2.trueWords();
int num2=w2.number;
System.out.println("num2="+num2);
}
// public static void printMessage(TwoDragonM t) {
// System.out.println("---> "+t.trueWords());
// }
// public static void printMessage(FenWine t) {
// System.out.println("---> "+t.trueWords());
// }
public static void printMessage(Wine t) {
System.out.println("---> "+t.trueWords());
}
}
class Wine{
String brand;
int grade;
double price;
int number=111;
public String trueWords() {
System.out.println("父类");
return "父类";
}
}
class TwoDragonM extends Wine{
int number=222;
@Override
public String trueWords() {
System.out.println("子类1");
return "子类1";
}
}
class FenWine extends Wine{
int number=666;
@Override
public String trueWords() {
System.out.println("子类2");
return "子类2";
}
}