java 详解接口、继承和多态

来源:互联网 发布:宋思明 知乎 编辑:程序博客网 时间:2024/04/27 17:19
接口、继承和多态
  继承和多态是面向对象开发语言中非常重要的一个环节,如若使用得当,可以将整个程序的架构变得非常有弹性,同时可以减少代码的冗余性。
继承机制的使用可以复用一些定义好的类,减少重复代码的编写。多态机制的使用可以动态调整对象的调用,降低对象之间的依存关系。同时为了优化继承与多态,除了使用继承还使用了接口的形式。

java语言中的类可以同时实现多个接口,接口被用来建立类与类之间的关联的标准,因为这些 机制,java于洋更具有生命力。


一.接口
  1.接口的定义
    使用interface来定义一个接口,接口定义与类的定义类似,也是分为声明和接口体,其中接口体由变量定义和方法定  义两部分组成。基本 语法格式如下:
    [修饰符]interface 接口名[extends 父接口名列表]{
    [public] [static][final]变量;
    [public] [abstract]方法;
   }
  2.语法格式的参数说明
   修饰符 可选参数,用于指定接库的访问权限。

   接口名 必选参数,用于指定接口的名称,接口名必须是合法的java标识符,一般情况下要求首字母大写


    extends父接口 可选参数,用于指定要定义的接口继承于哪一个父接口,当使用extends关键字时,父接口名为必选  参数方法 接口中的方法只有定义而没有被实现

  【例】定义一个用于计算的接口,在该接口中定义一个常量PI和两个方法
    
       public interface ICalculate{           final float PI=3.14159f;         //定义用于表示圆周率的常量           float getArea(float r);          //定义一个用于计算面积的方法getArea()           float getCircumference(float r); //定义一个用于计算周长的方法getCircumference()       }
  3.接口的实现
    接口定义后,就可以在类中实现接口,在类中实现接口可以使用implements关键字,基本语法格式如下:

     [修饰符]class<类名>[extends 父类名][implements 接口列表]{
     }
  4.实现接口的语法格式的参数说明:
 修饰符                 可选参数,用于指定类的访问权限,可选值为public、abstract和final
  类名                   必选参数,用于指定类的名称,类名必须死合法的java标识符,一般情况下要求首字符大写
  extends父类名   可选参数,用于指定要定义的类继承与那个父类,当使用extends关键字时,父类名为必选参数
 接口列表             可选参数,用于指定该类实现的哪些接口,当使用implements关键字时,接口列表为必选参数,当                                  接口列表 中存在多个接口名时,各个接口之间使用逗号分隔。

在类中实现接口时,方法名、返回值类型、参数个数及类型必须与接口中的完全一致,并且必须实现接口中的所有方法。

  【例】编写一个名称为Cire的类,该类实现定义的接口ICalculate
     
       public class Cire implements ICalculate{            //定义一个计算圆面积的方法            public float getArea(float r){                float area=PI*r*r;        //计算圆面积,并赋值给变量area                return area;              //返回计算后的圆面积             }            public float getCircumference(float r){                float circumference=2*PI*r;//计算圆周长,并赋值给变量circumference                return circumference;      //返回圆周长            }        } 
5.注意点:
1.接口不可以被实例化
2.实现类必须实现接口的所有方法
3.实现类可以实现多个接口

4.接口中的变量都是静态常量


二、类的继承
  在java语言中继承通过extends关键字来实现。也就是用extends指明当前类是子类,并指明从哪一个类继承而来,即   在子类的声明过程中,通过使用extends关键字来显示指明其父类。基本的声明格式如下:
  [修饰符] class 子类名 extends 父类名{
  类体
  }
1.参数说明
修饰符:可选参数,用于指定类的访问权限,可选值为:public、abstract、final
子类名:必选参数,用于指定子类的名称,类名必须是合法的java标识符,一般情况下要求首字母大写
extends父类名:必选参数,用于指定要定义的子类继承与那个父类。
【例】定义一个Pigeon类,继承于父类Bird
   
     父类Bird的代码:     public  class Bird{     String color="白色";     String skin="羽毛";     }          子类Pigeon代码:     public Pigeon extends Bird{         public static void main(String[] args){             Pigeon  Pigeon = new Pigeon ();             System.out.println("颜色:"+pigeon.color+"皮肤:"+pigeon.skin);         }     }



2.继承中的重写
重写是指父子类之间的关系,当子类继承父类中的所有可能被继承的成员方法时,如果子类的方法名与父类的方法名相同时, 子类就不能继承父类的方法,此时,则称为子类的方法重写了父类的方法。
重写体现了子类补充或者改变父类方法的能力,通过重写,可以使一个方法在不同的子类中表现出不同的行为(重写也可以 称为覆盖)。
【例】定义一个动物类Animal及它的子类,并在子类中重写父类的相关方法

     (1)创建一个名称为Animal的类,在该类中声明一个成员方法cry()。代码如下:        public class Animal{            public Animal(){                             }            public void cry(){            System.out.println("动物发出叫声!")            }        }     (2)创建一个Animal类的子类Dog,在该类中重写了父类成员的方法cry()。代码如下:        public class Dog extends Animal {             public Dog(){                }             /**             * 重写父类Animal的成员方法             */             public void cry(){         System.out.println("狗发出 “汪汪~~”的叫声!");             }        }     (3)创建一个Animal类的子类Cat,在该类中重写了父类成员的方法cry()。代码如下:            public class Dog extends Animal {             public Cat(){                }             /**             * 重写父类Animal的成员方法             */             public void cry(){         System.out.println("猫发出“喵喵~~”的叫声!!");             }        }     (4)创建一个Animal类的子类Sheep,在该类中不定义任何方法。代码如下:         public Sheep(){ //不重写方法,调用父类中的成员方法           }       (5)创建一个类Zoo,在该类的main方法中分别创建子类Dog、Cat和Sheep的对象并为该对象分配内存,然后调用各对象的cry()        方法。代码如下:        package com.java.study.chapter15_01;        /**         *类名称:Zoo.java         *类描述:动物园类Zoo         *类说明:         *创建时间:2016年12月15日,下午6:55:20         *lenovo         */        public class Zoo extends Animal {     public static void main(String[] args) {        /**         * 创建DOg类的对象,并为其分配内存         */         Dog dog =new Dog();          System.out.println("执行dog.cry();语句时输出的结果:"); dog.cry();/** * 创建Cat类的对象,并为其分配内存 */Cat cat =new Cat();System.out.println("执行cat.cry();语句时输出的结果:");cat.cry();/** * 创建Cat类的对象,并为其分配内存 */Sheep sheep =new Sheep();System.out.println("执行sheep.cry();语句时输出的结果:");sheep.cry();    }        }
从上面的运行结果中可以看出,由于Dog类和Cat类都重写了父类的cry()方法,所以执行的是子类中的cry()方法,但是Sheep类没有重写父类中的方法,所以执行的是父类中的cry()方法。

3.使用super关键字
子类可以继承父类中的非私有成员变量和成员方法(不是以privare修饰的)作为自己的成员变量和成员方法。但是,如果子类中声明的成员变量和父类的成员变量同名,则子类不能继承父类的成员变量,则称子类的成员变量覆盖了父类的成员变量。同样的情况下,子类中的成员方法与父类的成员方法同名,并且方法的返回值及参数的个数和类型也相同,则子类不能继承父类的成员方法,此 时称子类的成员方法重写了父类的成员方法。这时,如果在子类中访问父类中被隐藏的成员方法或变量,就可以使用super关键字。super关键字主要有两种用途:

1.调用父类的构造方法
子类可以调用父类声明的方法,但是必须在子类的构造方法中使用super关键字来调用,语法格式:super([参数列表]);如果 父类的构造方法包括参数,则参数列表为必选项,用于指定丰富类的构造方法的入口参数。
【例】创建一个Beast类,在类中添加一个默认的构造方法和一个带参数的方法。

       public class  Beast{           String skin="";         //成员方法           public Beast(){         //默认构造方法           }           public Beast(String strSkin){     //带参数的构造方法              skin=sreSkin;           }           public void  move(){              System.out.println("跑");           }        }                 在子类Tiger中使用父类的带参数的构造方法,则需要在子类Tiger的构造方法中进行调用。代码如下:        public class Tiger extends Beast{             public Tiger (){                //带参数的构造方法                 super("条纹");             }        }

2.操作被隐藏的成员变量和被重写的成员方法


如果想在子类中操作父类中被隐藏的成员变量和被重写的成员方法,也可以使用super关键字。语法格式如下:
super.成员变量名
super.成员方法名([参数列表])
【例】如果在子类Tiger的方法中改变父类Beast的成员变量skin的值,也可以使用如下的代码:
super.skin="条纹";
如果在子类Tiger的方法中改变父类Beast的成员方法move(),也可以使用如下的代码:
super.move();
三.多态
多态是面向对象程序设计的重要组成部分。在java语言中,通常使用方法的重载和多态实现类的多态性。

方法的重载是指在一个类中出现多个方法名相同,但参数个数和参数类型不同的方法,则称为方法的重载,在执行重载关系的方法时,将根据调用参数的个数和类型来区分具体执行的是哪个方法。
【例】定义一个名称为Calculate的类,在该类中定义两个名称为getArea()的方法(参数个数不同)和两个名称为getArea()的方法(参数个数不同)和两个名称为draw()的方法(参数类型不同)
public class Calculate {final float PI=3.14159f;//定义一个表示圆周率的常量PI/** * 求圆形的面积 */public float getArea(float r){float area=PI*r*r;return area;}/** * 求矩形的面积 * @return */public float getArea(float l,float w){  //重载getAreafloat area=l*w;return area;}    /**     * 画任意形状的图形     */public void draw(int a){  //定义一个用于画图的方法drawSystem.out.println("画"+a+"个任意形状的图形");}/** * 画指定形状的图形 * @param shape */public void draw(String shape){//重载draw方法System.out.println("画一个"+shape);}public static void main(String[] args) {Calculate calculate =new Calculate();//创建Calculate类的对象并为其分配内存float l=20;float w=30;float areaRectangle=calculate.getArea(l,w);//调用方法,求矩形的面积System.out.println("长为"+l+"宽为"+w+"的矩形的面积是:"+areaRectangle);float r=7;float areaCirc=calculate.getArea(r);//调用方法,求圆的面积 System.out.println("半径为"+r+"的圆形的面积为:"+areaCirc);int a=7;calculate.draw(a);calculate.draw("三角形");}   }




0 0
原创粉丝点击