在Java中不支持多继承,但是一个类可以实现多个接口。就像鸭子,可以飞,跑,游,我们可以用三个接口实现;对于多个接口的实现,须用implements关键字,而接口之间,用逗号隔开。
例1:
interface IFlying{
void Flying();
}
interface IRunning{
void Running();
}
interface ISwimming{
void swimming();
}
class Duck implements IFlying,IRunning,ISwimming{
public String name;
public Duck (String name){
this.name = name;
}
@Override
public void Flying() {
System.out.println(this.name+"天上飞");
}
@Override
public void Running() {
System.out.println(this.name+"地上跑");
}
@Override
public void swimming() {
System.out.println(this.name+"水里游");
}
}
public class Test {
public static void main(String[] args) {
Duck d = new Duck("白糖");
d.Flying();
d.Running();
d.swimming();
}
}
执行结果:
白糖天上飞
白糖地上跑
白糖水里游
这就是一个类实现多个接口,它们接口中的抽象方法必须要全部实现。
与类的继承不同的是,一个接口可以有一个以上的父接口,它们之间用逗号分隔,形成父接口列表。新接口将继承所有父接口中的常量、抽象方法和默认方法,但不能继承父接口中的静态方法,也不能被实现类所继承。
例2:
interface IRunning{
void Running();
}
interface ISwimming{
void swimming();
}
interface IAmphibian extends ISwimming,IRunning{
}
class Duck implements IAmphibian{
public String name;
public Duck (String name){
this.name = name;
}
@Override
public void Running() {
System.out.println(this.name+"地上跑");
}
@Override
public void swimming() {
System.out.println(this.name+"水里游");
}
}
接口间的继承相当于把多个接口合并在一起.
接口中的静态方法不能被子接口继承,也不能被实现该接口的类继承。对接口中静态方法的访问,可以通过接口名直接进行访问,即用“接口名.静态方法名()”的形式进行调用。
接口中的默认方法用default修饰符来定义,默认方法可以被子接口或被实现该接口的类所继承,接口中的默认方法有方法体,须通过接口实现类的实例进行访问,即通过“对象名.默认方法名()”的形式进行访问。
例3:在接口中定义默认方法和抽象方法,和静态方法
interface Face{
final static double PI = 3.14;//定义常量
//定义默认方法--计算面积
public default double area(int r){
return r*r*PI;
}
//定义抽象方法
double volume(int r,double h);
//定义静态方法
public static String show(){
return "我是静态方法";
}
}
public class Test implements Face{
//实现接口的方法
@Override
public double volume(int r, double h) {
return area(r)*h;
}
public static void main(String[] args) {
System.out.println(Face.show());
Test t = new Test();
System.out.println("圆柱的体积 = "+t.volume(1, 2.0));
}
}
结果如下:
我是静态方法
圆柱的体积 = 6.28
自定义的学生类要具备可以比较的功能,就需要接口来实现,介绍Comparable,Comparator两种比较机制
Comparable 接口只包括一个函数,它的定义如下
public interface Comparable<T> {
public int compareTo(T o);
}
Comparable具体的比较规则是按照 compareTo 方法中的规则进行。这种顺序称为 自然顺序。
compareTo 方法的返回值有三种情况:
class Sturdnt implements Comparable<Sturdnt>{
public String name;
public int score;
public Sturdnt(String name,int score){
this.name = name;
this.score = score;
}
@Override
public int compareTo(Sturdnt o) {
return this.score - o.score;
}
}
public class Test {
public static void main(String[] args) {
Sturdnt s1 = new Sturdnt("大飞",89);
Sturdnt s2 = new Sturdnt("白糖",90);
if(s1.compareTo(s2) > 0){
System.out.println("s1 > s2");
} else if (s1.compareTo(s2) < 0) {
System.out.println("s1 > s2");
}else {
System.out.println("s1 > s2");
}
}
}
Comparator可以在类的外部使用,然后把该接口实现类的匿名对象当作参数传给排序方法中。可以拥有多个接口实现类,实现按照不同属性进行排序
如例5:
class Sturdnt {
public String name;
public int score;
public Sturdnt(String name,int score){
this.name = name;
this.score = score;
}
@Override
public String toString() {
return "Sturdnt{" +
"name='" + name + '\'' +
", score=" + score +
'}';
}
}
class ScoreComparator implements Comparator<Sturdnt>{
@Override
public int compare(Sturdnt o1, Sturdnt o2) {
return o1.score -o2.score;
}
}
class NameComparator implements Comparator<Sturdnt>{
@Override
public int compare(Sturdnt o1, Sturdnt o2) {
return o1.name.compareTo(o2.name);
}
}
public class Test1 {
public static void main(String[] args) {
Sturdnt[] sturdnts = new Sturdnt[3];
sturdnts[0] = new Sturdnt("大飞",89);
sturdnts[1] = new Sturdnt("白糖",90);
sturdnts[2] = new Sturdnt("武松",99);
ScoreComparator scoreComparator = new ScoreComparator();
Arrays.sort(sturdnts,scoreComparator);
System.out.println(Arrays.toString(sturdnts));
NameComparator nameComparator = new NameComparator();
Arrays.sort(sturdnts,nameComparator);
System.out.println(Arrays.toString(sturdnts));
}
}
输出结果:
[Sturdnt{name=‘大飞’, score=89}, Sturdnt{name=‘白糖’, score=90}, Sturdnt{name=‘武松’, score=99}]
[Sturdnt{name=‘大飞’, score=89}, Sturdnt{name=‘武松’, score=99}, Sturdnt{name=‘白糖’, score=90}]
所有的类都是直接或间接地继承Object类而得到的。即如果某个类没有使用extends关键字,则该类默认为java.lang.Object类的子类。所以说Object类是所有类的源,也就是所有类的对象都可以使用Object的引用进行接收。
例:使用Object接收所有类的对象
class Student{}
public class Text {
public static void func(Object obj){
System.out.println(obj);
}
public static void main(String[] args) {
func(new Student());
}
}
执行结果:
Student@1b6d3586
介绍几个方法:
在Java中,“==”运算符用于比较两个变量本身的值,即两个对象在内存中的首地址,而equals()方法则是比较两个字符串中所包含的内容是否相同;如果要比较对象中内容,必须重写Object中的equals方法,因为equals方法默认也是按照地址比较的
例1:
class Student{
public int score;
public String name;
public Student(String name,int score){
this.name = name;
this.score = score;
}
public boolean equals(Object obj) {
if (obj == null) {
return false ;
}
if(this == obj) {
return true ;
}
// 不是Person类对象
if (!(obj instanceof Student)) {
return false ;
}
Student student = (Student) obj ; // 向下转型,比较属性值
return this.name.equals(student.name) && this.score==student.score ;
}
}
public class Text {
public static void main(String[] args) {
Student s1 = new Student("白糖",100);
Student s2 = new Student("白糖",100);
System.out.println(s1.equals(s2));
}
}
执行结果:true
注: 比较对象中内容是否相同的时候,一定要重写equals方法。
toString()方法的功能是将调用该方法的对象的内容转换成字符串,并返回其内容,但返回的是一些没有意义且看不懂的字符串,所以可以直接重写Object类中toString()方法
class Student{
public int score;
public String name;
public Student(String name,int score){
this.name = name;
this.score = score;
}
public String toString() {
return "Student{" +
"score=" + score +
", name='" + name + '\'' +
'}';
}
}
public class Text {
public static void main(String[] args) {
Student s1 = new Student("白糖",100);
System.out.println(s1);
}
}
执行结果:
Student{score=100, name=‘白糖’}