接口
定义:
接口是抽象方法和常量值得集合,从本质上讲,接口是一种特殊的抽象类。这种抽象类中只包含常量和方法的定义,而没有去实现。
格式:
interface 接口名 { }
接口中成员修饰符是固定的:(注意:定义接口时不能省略返回值类型)
成员变量:public static final
成员函数:public abstract
特点:
1.接口是对外暴露的规则。
2.接口是程序的功能扩展。
3.接口的出现降低了耦合性(实现了模块开发)。
4.接口可以用来多实现。
5.于继承关系类似,接口与实现类之间存在多态性。
6.接口的出现将“多继承”通过同一种形式体现出来,即“多实现”。
继承与实现的区别:
类与类之间称为继承,因为该类无论是抽象的还是非抽象的,它的内部都可以定义非抽象方法,这个方法可以被直接被子类使用。
类与接口之间是实现关系,因为接口中的方法都是抽象的,必须有子类实现才可以实例化,所以就用关键字:implements(实现)
接口与接口之间可以有继承关系,一个接口可以继承另一个接口,并添加新的属性和抽象方法。
java中为什么可以多实现,而不可以多继承?
——>因为如果继承的多个父类中定义了相同的方法,而方法内容不同,JVM无法判断选择哪个执行哪个父类方法,故存在安全隐患。而多实现就没有这个问题,即使多个接口中存在相同的方法,但是他们都没有定义方法体。
多实现的好处:
1.打破了单继承的局限性,扩展了功能。
2.一个继承另一个类的同时,可以实现多个接口。(如某个女星只能有一个亲爹,但是干爹就可以有很多)
抽象类与接口的区别:
共性:都是不断抽取出来的抽象概念。
区别1:
抽象类体现的是继承关系,一个类只能单继承。
接口体现的是实现关系,一个类可以多实现。
区别2:
抽象类中定义体系中的几把共性功能。
接口通常定义体系中对象的扩展功能。
区别3:
抽象类可以定义非抽象方法,供子类直接使用。
接口中方法都是抽象的,接口中的成员都有固定的修饰符。
多态
定义:
某个事物的多种存在形态。
例:动物中的猫狗。
/*
多态:可以理解为事物存在的多种体现形态。
人:男人,女人
动物:猫,狗。
猫 x = new 猫();
动物 x = new 猫();
1,多态的体现
父类的引用指向了自己的子类对象。
父类的引用也可以接收自己的子类对象。
2,多态的前提
必须是类与类之间有关系。要么继承,要么实现。
通常还有一个前提:存在覆盖。
3,多态的好处
多态的出现大大的提高程序的扩展性。
4,多态的弊端:
提高了扩展性,但是只能使用父类的引用访问父类中的成员。
5,多态的应用
*/
/*
动物,
猫,狗。
*/
abstract class Animal{
abstract void eat();
}
class Cat extends Animal{
public void eat(){
System.out.println("吃鱼");
}
public void catchMouse(){
System.out.println("抓老鼠");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("吃骨头");
}
public void kanJia(){
System.out.println("看家");
}
}
class Pig extends Animal{
public void eat(){
System.out.println("饲料");
}
public void gongDi(){
System.out.println("拱地");
}
}
//-----------------------------------------
class DuoTaiDemo {
public static void main(String[] args) {
//Cat c = new Cat();
//c.eat();
//Dog d = new Dog();
//d.eat();
//Cat c = new Cat();
/*
Cat c1 = new Cat();
function(c1);
function(new Dog());
function(new Pig());
*/
//Animal c = new Cat();
//c.eat();
function(new Cat());
function(new Dog());
function(new Pig());
}
public static void function(Animal a){//Animal a = new Cat();多态的应用
a.eat();
//a.catchMouse();
}
/*
public static void function(Cat c){
c.eat();
}
public static void function(Dog d){
d.eat();
}
public static void function(Pig p){
p.eat();
}
*/
}
细节:
1、成员变量
编译时期:看引用型变量所属的类中是否有所调用的变量。
运行时期:也看引用型变量所属的类是否有所调用的变量。、
总:成员变量无论编译还是运行,都看引用型变量所属的类(就是左边)
2、成员函数
编译时期:看引用变量所属的类中是否有所调用的成员。
运行时期:看对象所属的类中是否有所调用的成员,如果父子类中出现同名的方法,会运行子类中的方法,因为方法有覆盖特性。
总:编译看左边,运行看右边。
3.静态函数
编译时期:看引用型变量所属的类中是否有所调用的成员。
运行时期:看引用型变量所属的类是否有调用的成员。
总:编译和运行都看左边。
关键字:instanceof(判断是否属于该类型)
模版方法模式:
在定义功能时,功能的一部分是确定的,但是有一部分是不确定的部分,那么这时就把不确定的部分暴露出去,由该类的子类去实现。
例:
//模版方法模式(Template)
class TempalteDemo {
public static void main(String[] args) {
/*GetTime gt = new GetTime();
gt.getTime();*/
Demo d = new Demo();
d.getTime();
}
}
abstract class GetTime{
public final void getTime(){
//long start = System.currentTimeMillis();//这个是毫秒值
long start = System.nanoTime();//这个豪微秒值
code();
//long end = System.currentTimeMillis();
long end = System.nanoTime();
System.out.println("这个程序运行的毫秒值是:"+(end - start));
}
public abstract void code();//因为不确定具体是测什么代码的运行时间,所以抽象
}
//定义一个类,该类继承GetTime。将要测试的程序写入code()方法中。
class Demo extends GetTime{
public void code() {
for (int x = 0;x < 10000;x++){
System.out.print("*");
}
}
}