前几篇是Java的入门篇,主要是了解一下Java语言的相关知识,从本篇开始是Java的进阶篇,这部份内容能够帮助你们用Java开发一些小型应用程序,或者一些小游戏等等。ide
本篇的主题是接口、继承与多态,在看下面的内容以前,首先须要了解一下继承和多态。继承机制的使用能够复用一些定义好的类,减小重复代码的编写;多态机制的使用能够动态调整对象的调用,下降对象之间的依存关系。有了这些概念,再来看接口是作什么用的。测试
首先咱们须要知道,Java语言只支持单重继承,不支持多继承。这句话的意思就是一个类只能有一个父类,但咱们常常须要使用多继承来解决问题,因此Java语言提供了接口来实现类的多重继承功能。this
Java中使用interface来定义一个接口,接口定义与类类似(类的定义用的是class),下面直接上例子。spa
public interface ICalculate { final float PI = 3.1415f; // 定义常量PI,表示圆周率 float getArea(float r); // 定义用于计算面积的方法getArea() float getCircumference(float r); // 定义用于计算周长的方法getCircumference()
}
从上述代码能够看出,interface是定义了一个接口,接口名为ICalculate(接口通常能够用大写字母“I”开头),在接口中能够定义变量和方法,但须要注意的是这里的方法都不能写方法体,也即方法名后直接加“;”,而方法的实现是写到实现接口的类中的。还有一点须要注意的是,接口中的全部方法都必须在实现了该接口的类中实现(能够空实现)。code
接下来演示一下Eclipse中如何建立一个接口。对象
(1)首先在包上右键new一个Interfaceblog
(2)填写接口名并肯定继承
(3)编写代码接口
上面定义了一个接口,但要实现接口须要在类中用implements关键字,下面直接看例子,对应的接口是上例中的ICalculate。游戏
1 public class Calculate implements ICalculate { 2 3 @Override 4 public float getArea(float r) { 5 float area = PI*r*r; // 计算圆面积并赋值给area 6 return area; // 返回area的值 7 } 8 9 @Override 10 public float getCircumference(float r) { 11 float circumference = 2*PI*r; // 计算圆周长并赋值给circumference 12 return circumference; // 返回circumference的值 13 } 14 15 }
Eclipse中建立步骤以下:
(1)填写类名,点击Add添加接口
(2)输入查找接口并肯定
(3)接口导入后点击肯定,就能够看到以下界面,填写相应代码便可(建立的每一个接口中的方法都必须实现,能够空实现,因此不能删除这里的任何一个方法)
一个类能够实现多个接口,写法就是implements后的接口间以“,”隔开便可。若是变量冲突,则经过“接口名.变量”来明确指定变量的接口。
在Java中,使用extends关键字实现继承,extends后跟的是父类名,也就是它从哪一个类继承过来的,而用extends的这个类自己称为子类。
下面举个简单的例子,在生物学中,鸽子属于鸟的一种,因此鸟是父类,鸽子是子类。
父类:
public class Bird { String color = "灰色"; // 颜色 String skin = "羽毛"; // 皮毛 }
子类:
public class Pigeon extends Bird { public static void main(String[] args) { Pigeon pigeon = new Pigeon(); System.out.println(pigeon.color); } }
简单来讲就是,若是子类方法名和父类方法名相同,那么子类就不能继承父类的方法,此时称子类的方法重写了父类的方法。重写也可称为覆盖。
举个简单的例子,这是一个动物类,实现了一个voice方法:
public class Animal { public Animal() {} public void voice() { System.out.println("make some voice.."); } }
建立一个Animal类的子类Dog,重写voice方法发出狗叫:
public class Dog extends Animal{ public Dog() {} @Override public void voice(){ System.out.println("woof..."); } }
再建立一个Animal类的子类Cat,重写voice方法发出猫叫:
public class Cat extends Animal { public Cat() {} @Override public void voice(){ System.out.println("nya..."); } }
此时调用dog和cat中的方法都不会出现“make some voise..”字样,而是对应的狗叫和猫叫。
但若是此时再建立一个Animal类的子类,但不重写方法,此时输出为父类Animal中voice方法的内容,建立一个子类Fish以下:
public class Fish extends Animal{ public Fish() {} }
下面建立一个Zoo类,来调用上述几个方法测试一下:
public class Zoo { public static void main(String[] args) { Dog dog = new Dog(); dog.voice(); Cat cat = new Cat(); cat.voice(); Fish fish = new Fish(); fish.voice(); } }
运行结果以下:
从运行结果能够看出,因为Dog类和Cat类都重写了父类的方法voice(),因此执行其相应的方法,而Fish类中没有重写,因此执行的是父类中的方法。
子类能够调用父类声明的构造方法,可是必须在子类的构造方法中使用super关键字来调用;若是想在子类中操做父类中被隐藏的成员变量和被重写的成员方法,也能够使用super关键字。这些在之后的项目中会出现,这里就不举例了,若是使用Java编译器的话,须要使用super关键字但未使用时编译器会有错误提示。
在Java中,一般使用方法的重载和重写实现类的多态性。
重写在上面已经介绍过了,而方法的重载是指在一个类中出现多个方法名相同,但参数个数或参数类型不一样的方法,下面举个关于重载的例子。
好比求圆形和矩形的面积,是两个名称为getArea()的方法,它们的参数个数不一样,以下:
// 求圆形面积 public float getArea(float r) { float area = PI*r*r; return area; } // 求矩形面积 public float getArea(float a, float b) { // 重载getArea()方法 float area = a*b; return area; }
再好比添加一个学生的信息,是两个名称为setStudent()方法,它们的参数类型不一样,以下:
// 添加学生号 public void setStudent(int ID) { this.stu_id = ID; } // 添加求学生姓名 public void setStudent(String name) { this.stu_name = name; }
须要注意的是,在进行方法的重载时,方法返回值的类型不能做为区分方法的标志。