黑马程序员_<<面线对象(继承,abstract,interface,final)---02>>

--------------------ASP.Net+Android+IOS开发.Net培训、期待与您交流! --------------------


1. 继承

      1.概述

             继承是面向对象的第二大特征,其他两个是封装和多态。使用的是extends关键字,格式:class  A{}   class  B  extends A,

      继承就是把类之间共性的特征抽取出来但是两个类之间必须存在某种联系,然后才可以进行继承。

      例如:学生和工人,他们都有名字和年龄,但是他们都是人,所以可以把名字和年龄封装到Person类中,然后类Student和类Worker继承类Person,那么就可以不用写年龄和姓名属性,那么就会继承过来,前提:属性权限不能是私有的。

     例如:

class Person{
  String name;
  int age;
}
class Student extends Person{
 
}
class Workerextends Person{
 
}


当然里面还可以添加其他成员。

      继承的优点:提高代码的复用性,提高程序的扩展性,这样类之间就会存在某种关系,这样会出现了另一种面向对象的特性,那么就是多态。

      只能存在单继承,一个类只能继承一个类。

     2.成员变量

          当子类和父类中相同变量的时候,那么直接调用的话,那么会调用子类的,如果调用父类的话,那么就使用super关键字。

        子类会继承父类中非私有化的成员。

        

   public class Fu {
    public  String name="父类";
    public void show(){
    System.out.println(name);
    }
}
public class Zi extends Fu {
  public String name = "子类";
 
  public void show() {
    System.out.println("默认调用:"+name);
    System.out.println("父类的 super:"+super.name);
  }
 
  public static void main(String[] agrs) {
    Zi z = new Zi();
    z.show();
  }
}
结果:
默认 调用:子类
父类的 super:父类

 

           3.函数的继承

             子类继承父类后,会继承父类中的所有非私有的方法,如果子类想对其中的方法有自己的描述,那么就重写父类的方法,但是重写的方法的权限必须大于或者等于父类方法的访问权限。

        private<protected<default<public

覆盖(重写):当子类函数和父类函数定义完全一样时候,就是子类函数覆盖了父类的函数。

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

静态只能覆盖静态。

但是如果父类的方法是私有的,子类有相同的方法的话,也不能称为覆盖,原因是子类就不知道父类有此方法,所以不能称为覆盖。

 

   对于方法的重写,返回值,方法名,参数类型都必须相同,否则就不是重写父类的方法,也许编译会不通过。

   例如:动物都可以表达,但是表达的方法不一样,有的用嘴,有的用肢体,所以方式不同,所以对于动物的子类的表达方式需要重写动物的表达方法,定义自己的表达方法。

 

public class Fu {
    public void show(){
    System.out.println("父类这样展示");
    }
}
public class Zi extends Fu {
  public void show() {
    System.out.println("子类重写父类的show()方法,自己的show()");
  }
 
  public static void main(String[] agrs) {
    Zi z = new Zi();
    z.show();
  }
}
结果:
子类重写父类的show()方法,自己的show()


 

           4.构造方法

         子类中的构造函数默认的省略了super();相当于调用父类的无参构造函数。默认的调用父类的构造函数。

         若都不是隐式的话,则子类调用的函数也不能进行隐式调用。

         子类中的所有函数都会默认访问父类的无参的构造函数。如果父类中没有无参的构造函数,那么就手动使用super指定访问父类中的构造函数。

       

public class Fu {
  public Fu() {
    System.out.println("父类无参构造方法");
  }
}
public class Zi extends Fu {
  public Zi(){
    //这里省略了 super();
    System.out.println("子类无参构造方法");
  }
 
  public static void main(String[] agrs) {
    Zi z = new Zi();
  }
}
结果:
父类无参构造方法
子类无参构造方法


 

从结果可以看出,创建子类的对象的时候,首先会在子类的构造方法最前面调用父类的构造方法,然后执行本身的构造方法的函数体。

 

如果父类没有无参构造函数,那么子类需要指定调用父类相应的构造函数。

 

public class Fu {
  public Fu(Stringname) {
    System.out.println("父类有参构造方法");
  }
}
public class Zi extends Fu {
  public Zi(String name){
    super(name);
    System.out.println("子类有参构造方法");
  }
 
  public static void main(String[] agrs) {
    Zi z = new Zi("张三");
  }
}
结果:
父类有参构造方法
子类有参构造方法


 

 

         不管怎么样,子类必须调用父类的构造函数,不管是无参的,还是有参的。

          this().和super()在构造函数中,不能同时出现,因为他们要求的都是要定义在第一行,所有只能存在一个。

2.  final关键字

    

            特点;

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

       2.被final修饰的类不可以被继承。

       3.被final修饰的方法不能被复写。

       4.被final修饰的变量,只能赋值一次,及可以修饰局部变量,也可以修饰全局变量。通 常是大写组成。

       内部类只能访问被final修饰的局部变量。

 

class Demo {
  public final double PI = 3.14;// 这样一般大写,不可以被修改,一般都是把对象是统一的,切不能不修改的变量
 
  public final void show() {// 此方法不能被重写
    System.out.println("helloworld");
  }
 
  public void print() {// 此方法可以被重写
    System.out.println("print()");
  }
}
 
class DemoZi extends Demo {
  public void print() {// 此方法可以被重写
    System.out.println("DemoZiprint()");
  }
 
  public static void main(String[] agrs) {
    DemoZi zi = new DemoZi();
    zi.show();
    zi.print();
  }
}
结果:
hello world
DemoZi print()


 

3.abstract关键字

              1.概述

             1.abstract修饰的类中可以定义抽象方法和非抽象方法。

     2.普通类中不能定义抽象方法。

     3.抽象类不可以用new创建对象,抽象类中的方法要被使用,则必须由子类复写方法后,有子类对象使用。

     4.只要类中有抽象方法,那么此类必须是抽象类,

         特殊:抽象类中可以不定义抽象方法,只是为了不让其创建对象。

     只要是把相同的功能抽取出来,但是此类没有存在对象的特定意义,其中的抽象方法无方法体,只是给出了其功能的显示,让你子类对其重写。那么就把其定义成抽象类。

 

 

   **
 * 描述人的类
 */
abstract class Person {
  private String name;
 
  public Person(String name) {
    this.name = name;
  }
 
  /*
   * 人都要工作,只是工作的方式不一样学生要工作,那就是学习,工人要工作:那是上班但是他们之间不饿能存在继承关系,否则他们之间的关系就乱了。
   * 那么定义成抽象方法,那么子类就必须重写此方法,不会存在不重写就会继承父类的方法体内容(因为父类中抽象方法没有方法体)
   */
  public abstract void work();
}
 
class Work extends Person {
  public Work(String name) {
    super(name);
  }
 
  @Override
  public void work() {
    System.out.println("工人工作");
  }
}
 
class Student extends Person {
  public Student(String name) {
    super(name);
  }
 
  public void work() {
    System.out.println("学生工作");
  }
 
}

 

           2.模版方法

                   方法中的一部分功能确定,一部分没有确定,那么把不确定的部分封装成一个方法,然后公布出去,每当使用此方法,那么就先把不确定的方法体的方法重写,然后调用此方法。

     

 abstract class Demo {
  public final void getRunTime() {
    long start= System.currentTimeMillis();
    runCode();
    long end = System.currentTimeMillis();
    System.out.println("运行时间:" + (end - start));
  }
 
  public abstract void runCode();
}

    这样就确定了运行的代码,那么就可以计算时间,那么这样就可以多次使用这样的模版方法了。

4. 接口

        1.接口中的方法全是抽象的。

         Public static final 常量;

         Public abstract 返回值方法名();

         接口中的成员都是public的

        常量如果不写修饰,默认的是Public static final

        方法不写修饰的话,则默认的是Public abstract

    2.接口不能被实例化,

    3.接口可以被类多实现。一个类可以事件多个接口,一个接本也可以继承多个接口。

        interface   A{}   class B implements A{}  类实现接口

        interface  B{}  interface C{}   interface D extends B,C  接口多继承接口

         class D implements A,B 类可以都实现多个接口

           注意点:继承或者实现的多个接口中,不能有相同的方法名的抽象方法但是返回值类型不相同。这样编译器就会报错,原因是不知道要重写那一个方法。  当一个类既有继承类,又要实现接口,那么就先继承类然后实现接口,class E extends A extends X

    4.接口特点:

      接口对外暴露的规则

      接口是程序的功能扩展

      接口实现多实现

      类可以继承一个类的同时可以实现多个接口

      接口与接口之间可以实现多继承关系。

   5.接口实现举例:

      可以讲不是共有的功能放到接口中,谁具有此接口中的功能,谁就实现它。

      可以定义规则,例如电脑上的USB接口,只要是USB接口,那么就可以插入,不管是什么设备,USB就是一个接口,那么还有设备就是其子类。

 

--------------------ASP.Net+Android+IOS开发.Net培训、期待与您交流! --------------------


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值