黑马程序员_05_继承

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ---------------------- 
继承的概述

多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承单独的那个类即可。
多个类可以称为子类,单独这个类称为父亲或者超类。
子类可以直接访问父类中的非私有的属性和行为。

通过extends关键字让类与类直接产生继承关系。
      Class SubDemo extends Demo{}

好处:
继承的出现提高了代码的复用性。
继承的出现让类与类直接产生了关系,提供了多态的前提。

4.1继承的特点
· java只支持单继承,不支持多继承。
       一个类只能有一个父类,不可以有多个父类。一个孩子只能有一个爹。
       Class SubDemo extends Demo{} //ok
       Class SubDemo extends Demo1,Demo2…{}//error

java语言中:java只支持单继承,不支持多继承。

因为多继承容易带来安全隐患:当多个父类中定义了相同功能,但功能内容不同时,子类对象不确定要运行哪一个。譬如c如果继承了a 和b,a和b如果有一个同名函数,但是内容不同,会有安全隐患
但是java保留这种机制。并用另一种体现形式来完成表示——多实现。

 Java支持多层继承(继承体系)

   
   
Class A{}

Class B extends A{}

Class C extends B{}
先查阅体系父类的描述,因为父类中定义的是该体系中共性功能。

通过了解共性功能,就可以知道该体系的基本功能。那么这个体系已经可以基本使用了。如上面的A继承体系中,A中的内容有B和C的所有共性内容。C当然可以使用A中的内容。
那么在具体调用时,要创建最子类的对象,为什么呢?
一是因为有可能父类不能创建对象(如抽象类作为父类)
二是创建子类对象可以使用更多的功能,包括基本的也包括特有的。(就是包括父类和子类的功能都能使用,因为子类继承了父类的功能)

简单一句话:查阅父类功能,创建子类对象使用功能。
·定义时要注意:
       不要为了获取其他类中的某个功能而去继承
      类与类直接要有所属“is a”关系,xx1是xx2的一种。

代码演示:

class Person//有2个类继承,成为父类

{
      String name;//
      int age;//这两个特征,每个人都有,共性
}
学生的特性里面Person类里面都有,属于人这个类中的一种,是“is a”的关系,所以可以继承。继承了以后可以提高了代码的复用性
  
  
class Student extends Person
{
  void study() //学生中的特别熟悉,会学习
      {
           System.out.println("goodstudy");
      }
}         

class Workerextends Person//工人的特性里面Person类里面都有,所以可以继承。继承了以后可以提高了代码的复用性

{
      void work()//学生中的特别熟悉,会学习
      {
           System.out.println("goodwork");
      }
}
   
   
class ExtendsDemo
{
      public static void main(String[] args)
      {
           Student s = new Student();
           s.name = "zhagnsan";
      }
}

子父类中变量的特点
类中成员包括
1,变量。
2,函数。
3,构造函数。
子父类出现后,类成员的特点:
变量:
如果子类中出现非私有的同名成员变量时,
子类要访问本类中的变量,用this
子类要访问父类中的同名变量,用super。
super的使用和this的使用几乎一致。
this代表的是本类对象的引用。
super代表的是父类对象的引用。
堆内存中的加载:
加载子类,首先会加载父类,虽然num同名,但是子类中也有num。权限够就可以访问。
方法区的加载,子类中有this和super的引用,这样就可以调用父类的方法了。
演示代码2

class Fu

{
      int num = 4;
}

class Zi extendsFu
{
      int num = 5;
      void show()
      {
//num前面省略的是一个this.。如果子类中没有num,前面也是默认this,但是调用的是父类中的num。运用的是多态,子类对象指向父类。
           System.out.println(num);
      }
}
   
   
class  ExtendsDemo2
{
      public static void main(String[] args)
      {
           Zi z = new Zi();
           z.show();//输出的是5,
           System.out.println(z.num+"...."+z.num);//输出语句都是zi类的num
      }
}
Super关键字
super的使用和this的使用几乎一致。
this代表的是本类对象的引用。
super代表的是父类对象的引用。
演示代码2
   
   
class Fu
{
      int num = 4;
}
class Zi extendsFu
{
      //int num = 5;如果把这一行隐藏,show输出的语句System.out.println(num);输出结果是?答案是4.因为本类的中没有num的话,自动会从父类中寻找
      void show()
      {
           System.out.println(super.num);// super.代表的是父类的引用。如果int num=5那行指令隐藏,此条输出的num是4。不写super.输出的也是4.此时的num前面默认隐藏了super.
           //System.out.println(thisr.num);这条语句输出的也是4。原因在多态里面讲到
      }
}


   
   
class  ExtendsDemo2
{
      public static void main(String[] args)
      {
           Zi z = new Zi();
           z.show();//此时输出的是4
      }
}




子父类中的函数特点:覆盖

当子类出现和父类一模一样的函数时,子类对象调用该函数,会运行子类函数的内容。

如同父类的函数被覆盖一样。

这种情况是函数的另一个特性:重写(覆盖)


作用:

当子类继承父类,沿袭了父类的功能,到子类中,

但是子类虽具备该功能,但是功能的内容却和父类不一致,

这时,没有必要定义新功能,而是使用覆盖特殊,保留父类的功能定义,并重写功能内容。

覆盖:

1,        子类覆盖父类,必须保证子类权限大于等于父类权限,才可以覆盖,否则编译失败。

权限修饰符现在学了三种public,private,default(不写的时候默认就是这个)

2,静态只能覆盖静态。

重载与重写

重载:只看同名函数的参数列表。

重写:子父类方法要一模一样。

演示代码:
   
   
class Fu
{
      void show()//如果void换成int,返回值为int,可以吗?答案是不可以,因为重写必须要一模一样,不同的返回值不是重写,有可能编译失败。
      {
           System.out.println("fushow");
      }
/*如果这个函数前面加个private修饰,编译成功,但是无法覆盖。因为私有化以后只能被本类访问了,子类不知道有这个功能了,不能叫做覆盖。如果前面加一个public,编译失败,因为子类权限必须大于等于父类权限,public修饰以后,子类中的同名函数权限小,无法完成覆盖*/
      void speak()
      {
           System.out.println("vb");
      }
}


class Zi extendsFu
{
      void speak()//父类中有speak,子类中也用,这个类的内容和父类中的不一样,使用覆盖特殊,保留父类的功能定义,并重写功能内容。这个就是重写(也叫覆盖)
      {
           System.out.println("java");
      }
      void show()//如果这个函数前面加个private修饰,编译不成功,因为子类权限必须大于等于父类权限,这private修饰以后,比default权限小,编译失败。如果前面加一个public,编译成功,因为子类权限必须大于等于父类权限,public修饰以后,子类中的同名函数权限比父类的大,可以完成覆盖
      {
           System.out.println("zishow");
      }
}
classExtendsDemo3
{
      public static void main(String[] args)
      {
           Zi z = new Zi();
           z.show();//输出的是zi show,因为当子类出现和父类一模一样的函数时,子类对象调用该函数,会运行子类函数的内容。
      }
}
class Tel
{
      void show()
      {
           System.out.println("number");
      }   
}
class NewTelextends Tel
{
      void show()//重写的作用是在避免改写源代码的基础上,增加新的功能。源代码更改牵一发而动全身,一般不更改。这时候利用重写就可以进行升级。实现扩展的功能。
      {
           //System.out.println("number");
           /*super的使用,直接用父类的show函数。不能直接写show(),这样的话前面默认省略this.,this.show(),直接使用本    身的函数,出现递归了。所以用super.show(),这样使用父类中的函数,简单。*/
   super.show();
           System.out.println("name");//增加新的功能,利用重写,很方便
           System.out.println("pic");
      }
}

子父类中构造函数的特点:子类实例化过程


特点:在对子类对象进行初始化时,父类的构造函数也会运行。

那是因为子类的构造函数默认第一行有一条隐式的语句 super();

super():会访问父类中空参数的构造函数。而且子类中所有的构造函数默认第一行都是super();

为什么子类一定要访问父类中的构造函数?

因为父类中的数据子类可以直接获取。所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的。

所以子类在对象初始化时,要先访问一下父类中的构造函数。

如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定。

注意:super语句一定定义在子类构造函数的第一行。

子类的实例化过程:

子类的所有的构造函数,默认都会访问父类中空参数的构造函数。因为子类每一个构造函数内的第一行都有一句隐式super();

当父类中没有空参数的构造函数时,子类必须手动通过super语句形式来指定要访问父类中的构造函数。

当然:子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数。

子类中至少会有一个构造函数会访问父类中的构造函数。

问题:

为什么this()super()不能同时在构造函数中?因为只能有一个在第一行(这是规定)

为什么this()super()语句必须都得在第一行?因为初始化动作要先做。

为什么子类一定要访问父类的构造函数?

因为父类中的数据子类可以直接获取。所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的。所以子类在对象初始化时,要先访问一下父类中的构造函数。如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定。

注意:super语句一定定义在子类构造函数的第一行。

结论:

子类的所有的构造函数,默认都会访问父类中空参数的构造函数。

因为子类每一个构造函数内的第一行都有一句隐式super();

当父类中没有空参数的构造函数时,子类必须手动通过super语句形式来指定要访问父类中的构造函数。

当然:子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数。

子类中至少会有一个构造函数会访问父类中的构造函数。

演示代码:

class Fu //extends Object 默认隐藏语句,所有的父类都继承Object

{//super();这个继承的父类是Object

      int num;

      Fu()

      {

           Num =60;//为什么一定要访问父类中的构造函数呢?因为子类继承了父类的全部特征,如果子类中会用到num必须先访问父类中的num,对num进行父类初始化。如果不访问构造函数的话,num的默认值为0了。父类中的数据子类可以直接获取。所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的。所以子类在对象初始化时,要先访问一下父类中的构造函数。

            System.out.println("furun");

      }

      /* 如果写上下面这个函数,Zi(int x)运行的时候会运行这个吗?答案是ibu会,因为子类默认的隐藏语句是super(),不会执行这父类第二个构造函数Fu(int  x)

      Fu(int x)

      {

           System.out.println("fu...."+x);

      }

*/

}

class Zi extendsFu

{

      Zi()

      {//为什么默认是super(),因为如果父类没有内容,为空,这样也可以执行,所以默认的是    super()。

           //super();在子类构造函数中默认会有一条这个指令,只要执行子类构造函数,就会先执行父类的构造函数。子类中所有的构造函数默认第一行都是super();从这里可以联想到this(),构造函数直接调用只能使用this()语句。Super()在这里是子类用来调用父类的。This()和super()两个语句使用方法是一样,this就是本类的引用,譬如构造函数之间;super就是父类的引用,譬如子类构造函数引用父类的构造函数。

           System.out.println("zirun");

      }

      Zi(int x)

      {

           //this();如果在子类中使用这个this()指令,这个子类构造函数就没有super()函数了,因为两者只能存在一个。当有this()的时候,本函数,就不会访问父类构造函数。因为this()语句会访问Zi()函数,而Zi()内会优先访问父类构造函数

//子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数。子类中至少会有一个构造函数会访问父类中的构造函数。

           //super();//这个函数是属于子类第二个构造函数,所以第一行默认有这条指令。每次调用这个构造函数,会先调用父类的构造函数一次。

           //super(3);如果不访问fu(),想只访问Fu(int  x),可以用这个指令。当写了这个指令以后,就不会默认执行super()指令,直接执行Fu(int x=3)

           System.out.println("zi..."+x);

      }

}

class  ExtendsDemo4

{

      public static void main(String[] args)

      {

           Zi z = new Zi();//输出的是fu run zirun,子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的。所以子类在对象初始化时,要先访问一下父类中的构造函数。在子类构造函数中默认会有一条这个指令super(),只要执行子类构造函数,就会先执行父类的构造函数。

           Zi z1 = new Zi(4);//输出什么?答案是

fu run

zi…4

//原因是z1调用zi中的Zi(int x)函数,运行这个函数之前,会先调用父类的构造函数,fu run,然后才输出zi…4

      }

}

/*

class Person

{

      private String name;

      Person(String name)

      {

           this.name = name;

      }

      void show(){}

}

class Studentextends Person

{

      Student(String name)

      {

           super(name);//因为父类中的name都被私有化,子类如果用super.name = name这个指令是访问不到,直接用super(name);可以访问,并且很方便。

      }

      void method()

      {

           super.show();//父类中的方法,子类直接拿过来就可以用。利用super语句

      }

}

*/

另一个演示代码:

class Fu

{

      Fu(int x)

      {

           System.out.println("fu...."+x);

      }   

}

class Zi extendsFu

{

      Zi()

      {   

           //系统默认会有一个super(),这样的话因为父类中没Fu(),所以会编译失败,若想编译成功,必须在首行加入super语句,手动指定先要访问父类中的哪一个构造函数

           Super(4);//这个时候就不能用隐式语句了,必须写出来。当父类中没有空参数的构造函数时,子类必须手动通过super语句形式来指定要访问父类中的构造函数。

           System.out.println("zirun");

      }

      Zi(int x)

      {

           Super(6);

           System.out.println("zi..."+x);

      }

}

4.6 Final关键字


final : 最终。作为一个修饰符,

1,可以修饰类,函数,变量。

2,        被final修饰的类不可以被继承。(继承的一个弊端就是打破了封装性)

为了避免被继承,被子类复写功能。Finalclass 意思就是最终类,不能被子类继承

3,被final修饰的方法不可以被重写。

4,被final修饰的变量是一个常量只能赋值一次,既可以修饰成员变量,有可以修饰局部变量。当在描述事物时,一些数据的出现值是固定的,那么这时为了增强阅读性,都给这些值起个名字。方便于阅读。      而这个值不需要改变,所以加上final修饰。作为常量:常量的书写规范所有字母都大写,如果由多个单词组成。     单词间通过_连接。

5,内部类定义在类中的局部位置上是,只能访问该局部被final修饰的局部变量。

 

演示代码:

final classDemo1{}//这个类就是最终类,无法被别的子类继承的。

class Demo

{

      final int x = 3;//被final修饰的变量是一个常量只能赋值一次,既可以修饰成员变量,有可以修饰局部变量。此时父类Demo中x值为3,子类继承的时候不能改变的。

final int DA= 3//当在描述事物时,一些数据的出现值是固定的,那么这时为了增强阅读性,都给这些值起个名字。方便于阅读。

final int MY_PI= 3//当在描述事物时,一些数据的出现值是固定的,那么这时为了增强阅读性,都给这些值起个名字。方便于阅读。即使使用一次也最好起个名字,方便阅读!写代码,阅读性很重要!

//如果在写一个x=3;这个指令,是错误的,虽然都是3,但是这个指令的意思是再一次赋值。上面x已经被final修饰了,无法再赋值,所以错误。

      public static final double PI = 3.14;//这个变量首先用public修饰,权限最大,用static修饰,说明是静态的,优先于对象存在于方法区内,被所以独享共享。final是最终值,表示在这个类中,永远不会改变。

      final void show1()//被final修饰的方法不可以被重写。这个类只能引用

      {}

      void show2()

      {

           final int y = 4;

  //y=4;语法错误这个指令,是错误的,虽然都是4,但是这个指令的意思是再一次赋值。上面x已经被final修饰了,无法再赋值,所以错误。

           System.out.println(3.14);

      }

}

class SubDemoextends Demo

{

      //void show1(){}作为一个程序猿你也许认为自己不重写,上面那个show1也就不用加final了,是吧?但是自己不覆写,不代表别人不能。为了使代码更加严谨,所以该加final的一定要加上。

}

class FinalDemo

{

      public static void main(String[] args)

      {

           System.out.println("HelloWorld!");

      }

}

扩展思维:

现在学到能修饰类的有几个修饰符?

答案:public和final。Private不能修饰类的。第三个是default 。

4.7  抽象类


定义:

抽象就是从多个事物中将共性的,本质的内容抽取出来。

例如:狼和狗的共性都是犬科,犬科就是抽象出来的概念。

抽象类:

java中可以定义没有方法体的方法,该方法的具体实现由子类完成,该方法称为抽象方法,包含抽象方法的类就是抽象类

抽象类的由来:

多个对象都具备相同的功能,但是功能具体内容有所不同,那么在抽取过程中,只抽取了功能定义,并未抽取功能主体,那么只有功能声明,没有功能主体的方法称为抽象方法。

当多个类中出现相同功能,但是功能主体不同,这时可以进行向上抽取。这时,只抽取功能定义,而不抽取功能主体。

(函数有两部分:函数声明和函数主体)

抽象类的的特点:


1,抽象方法一定在抽象类中。

2,抽象方法和抽象类都必须被abstract关键字修饰。(不能定义变量,抽象类中可以没有抽象方法,作用就是不让该类建立对象,不多见)

3,抽象类不可以用new创建对象。因为调用抽象方法没意义。(因为抽象方法没有主体)

4,抽象类中的抽象方法要被使用,必须由子类复写起所有的抽象方法后,建立子类对象调用。如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。

格式:

abstract classStudent

{

      abstract finalvoid study(); //注意格式

}

用abstract修饰类名,然后再在要被抽象的方法前加abstract,因为只用声明,没有主体,函数的结束语句不是}就是;,没有主体所以在最后加上一个;。

抽象方法一定在抽象类中。

new Student()这样的语句是错误,因为Student类是个抽象类,没有对象无法调用,但是如果这样new Student().study()是可以的,因为study是个方法,匿名函数可以调用一次,虽然里面没有内容,但是是可以执行的。

演示代码:

abstract classStudent

{

      abstract void study();

      abstract void study1();

}

classBaseStudent extends Student

{

      void study()

      {

           System.out.println("basestudy");

           // bstract void study1();//继承Student,所以默认他还有另外一个函数语句abstract void study1();如果想不让子类是抽象的,必须重写父类中的所用方法才行。

}

}

当BaseStudent继承Student的时候,因为子类BaseStudent只重写了一个方法study(),又因为他继承Student,所以默认他还有另外一个函数语句abstract void study1();又因为抽象方法一定在抽象类中,所以这个部分继承抽象父类的子类也必须是抽象的。如果想不让子类是抽象的,必须重写父类中的所用方法才行。

抽象类是怎么来的?

譬如上面的学生学习,每个人学习的内容不一定全部一样,所以有个抽象类父类,子类可以建立对象,执行不同内容的学习。

抽象类和一般类没有太大的不同。

该如何描述事物,就如何描述事物,只不过,该事物出现了一些看不懂的东西。

这些不确定的部分,也是该事物的功能,需要明确出现。但是无法定义主体。

通过抽象方法来表示。

抽象类比一般类多个了抽象函数。就是在类中可以定义抽象方法。

抽象类不可以实例化。

演示代码:

abstract classStudent//抽象类,抽象方法一定在抽象类中

{

      abstract final void study();//抽象类中的抽象函数

      void sleep()//抽象类包含了一遍函数。其实抽象类和一般类没什么区别,只不过有看不懂的函数而已

      {

           System.out.println("躺着");//每个子类都有的共性,完全可以在父类中建立函数,让子类去继承

      }

}

classChongCiStudent extends Student//子类继承抽象父类

{

      void study()//重写函数study()

      {

           System.out.println("chongcistudy");

      }

}

classBaseStudent extends Student

{

      void study()

      {

           System.out.println("basestudy");

      }

}

classAbstractDemo

{

      public static void main(String[] args)

      {

          

      }

}

抽象练习演示代码,给员工建模

abstract classEmployee//父类员工

{

      private String name;

      private String id;

      private double pay;//私有化三个成员变量,仅对内部访问。

      Employee(String name,String id,double pay)

      {

           this.name = name;

           this.id = id;

           this.pay = pay;//this函数使用,是局部变量的值赋给类中成员变量

      }   

      public void work();//抽象化work(),public修饰可以公开权限,abstract修饰这个函数,抽象化

}

class Managerextends Employee

{

      private int bonus;

      Manager(String name,String id,doublepay,int bonus)

      {

           super(name,id,pay);//调用父类的构造函数。调用这个构造函数之前,会先访问父类中的构造函数。

           this.bonus = bonus;

      }

      public void work()//重写父类中的work()函数,使员工的工作内容更加具体。

      {

           System.out.println("managerwork");

      }

}

class Proextends Employee//建立经理的类,继承父类

{

      Pro(String name,String id,double pay)

      {

           super(name,id,pay);

      }

      public void work()//重写父类中的work()函数,使经理的工作内容更加具体。

      {

           System.out.println("prowork");

      }

}

class 

{

      public static void main(String[] args)

      {

           System.out.println("HelloWorld!");

      }

}

问题:

1:抽象类中是否有构造方法?不能实例化,为什么有构造方法?

2,抽象关键字abstract不可以和哪些关键字共存?

3.抽象类中可以没有抽象方法,这样的类有什么用吗?

4.JAVA中不能多继承,但所有类有都是object的子类,如果student是person类的子类,但student同时又是

  object的子类,这不是student extends person,object吗??

答案:

1.抽象类有构造方法。抽象类不能被实例化。 抽象类中的构造方法供子类实例化调用。

2. **private:

                        私有内容子类继承不到,所以,不能重写。

                        但是,abstract修饰的方法,要求被重写。两者冲突。

           **final

                        final修饰的方法不能被重写。

                        而abstract修饰的方法,要求被重写。两者冲突。                       

                **static

                        假如一个抽象方法能通过static修饰,那么这个方法,就可以直接通过类名调用。

                        而抽象方法是没有方法体的,这样的调用无意义。所以,不能用static修饰。

3. 抽象类是把所有类的共性集中,可以用于模块化设计,

4.一个类如果是经继承另一个类,将不会继承object类,因为他的父类

   已经继承object类,实现多层继承,这样的关系是:Person extends Object,Student extends Person

什么是模版方法呢?

在定义功能时,功能的一部分是确定的,但是有一部分是不确定,而确定的部分在使用不确定的部分,那么这时就将不确定的部分暴露出去。通过继承由该类的子类去完成。

abstract classGetTime//类内有抽象函数,这是个抽象类

{

      public final void getTime()//这个函数就是一个模板,不会改变,用final修饰

      {

           long start =System.currentTimeMillis();

 

           runcode();//这个函数如果被子类调用的时候,运行的是子类中runcode

            longend = System.currentTimeMillis();

           System.out.println("毫秒:"+(end-start));

      }

      public abstract void runcode();//因为具体怎么运行不太清楚,所以把该函数抽象化,这样具体的功能由子类去完成。这个思想就是个模板

}

class SubTimeextends GetTime

{

      public void runcode()//重写runcode函数,完成具体的功能

      {         

           for(int x=0; x<4000; x++)

           {

                 System.out.print(x);

           }

      }

}

class  TemplateDemo

{

      public static void main(String[] args)

      {

           //GetTime gt = new GetTime();

           SubTime gt = new SubTime();

           gt.getTime();

      }

}

三个问题:

1:抽象类中是否有构造方法?不能实例化,为什么有构造方法?

有构造函数,虽然抽象类不能被实例化,但是抽象类中的构造方法供子类实例化调用。

2,抽象关键字abstract不可以和哪些关键字共存?

private: 私有内容子类继承不到,所以,不能重写。但是,abstract修饰的方法,要求被重写。两者冲突。

Final: final修饰的方法不能被重写。而abstract修饰的方法,要求被重写。两者冲突。                       

Static:假如一个抽象方法能通过static修饰,那么这个方法,就可以直接通过类名调用。而抽象方法是没有方法体的,这样的调用无意义。所以,不能用static修饰。
3.抽象类中可以没有抽象方法,这样的类有什么用吗?

有,用来不然该类创建对象

4.8 接口


定义:

接口:初期理解,可以认为是一个特殊的抽象类。

      当抽象类中的方法都是抽象的,那么该类可以通过接口的形式来表示。

class用于定义类,

interface 用于定义接口。

格式:

Interface{}

接口定义时,格式特点:

1,接口中常见定义:常量,抽象方法。

2,接口中的成员都有固定修饰符。

      常量:public static final (final和static和public都是都默认系统自动加上去的)

      方法:public abstract (public是都默认系统自动加上去的)

记住:接口中的成员都是public的。

接口:

是不可以创建对象的,因为有抽象方法。

需要被子类实现,implement,子类对接口中的抽象方法全都覆盖后(要覆盖接口中的函数权限必须一样大,所以一般实现的子类一般函数前都加public),子类才可以实例化。否则子类是一个抽象类。

类为什么要抽象类?因为父类里面有抽象内容可以直接拿过来用,继承

接口,子类把接口里的内容都实现后才能实例化

接口可以被类多实现,也是对多继承不支持的转换形式。java支持多实现。

类与类之间是继承关系,类与接口直接是实现关系,接口与接口之间是继承关系。

演示函数:

interface Inter//接口Inter,interface 类名,建立一个接口,每一个接口都是一个类

{

      public static final int NUM = 3;//接口内部的变量,前面修饰符为public static final

      public abstract void show();//接口内部的函数,前面有public abstract 修饰

}

interface InterA

{

      public abstract void show();

}

class Demo

{

      public void function(){}

}

class Testextends Demo implements Inter,InterA//Test继承Demo类,同时实现Inter,InterA两个接口。Test属于Demo中的一员,同时还能做其他的事情。扩展性很强。

{//不能多继承,因为继承父类有方法体,继承多了会出现同名方法。而接口里面没有方法体,可以多实现

      public void show(){}

}

interface A

{

      void methodA();

}

interface B extendsA

{

      void methodB();

}

interface Cextends B//接口之间的关系,继承关系。接口直接可以实现多继承,如果b没有继承a,那么c可以extends B,A,因为都没有方法体,所以可以实现多继承。普通的类是无法实现多继承的。假如A和B中有不同的方法体,那么C就不能多继承了。

{

      void methodC();

}

class Dimplements C//这个时候d要是想实现c必须覆盖3个方法,不覆盖无法进行实例化

{

      public void methodA(){}//要覆盖必须加public

      public void methodC(){}

      public void methodB(){}

}

classInterfaceDemo

{

      public static void main(String[] args)

      {

           Test t = new Test();

           System.out.println(t.NUM);

           System.out.println(Test.NUM);

           System.out.println(Inter.NUM);//上面三条指令相同,Test实现接口Inter,所以对象t.NUM,Test.NUM,以及Inter.NUM都是可以实现的。但是不可以对num赋值,因为有final修饰num。接口中的变量都是常量了,不能赋值的。

      }

}

4.1 接口的特点

接口是对外暴露的规则

接口是程序的功能扩展。

接口可以用来多实现。

类与接口直接是实现关系,而且类可以继承一个类的同时实现多个接口。

接口与接口直接可以有继承关系。


------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------详细请查看:http://edu.csdn.net
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值