java 详解接口、继承和多态

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

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){  //重载getArea
		float area=l*w;
		return area;
	}
    /**
     * 画任意形状的图形
     */
	public void draw(int a){  //定义一个用于画图的方法draw
		System.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("三角形");
	}
   }




posted @ 2016-12-16 21:19  傲骄鹿先生  阅读(167)  评论(0编辑  收藏  举报