黑马程序员-java面向对象三大特性

来源:互联网 发布:mysise php爬虫 编辑:程序博客网 时间:2024/06/08 07:58
-------android培训java培训、期待与您交流! ----------


面向对象的三大特性:封装、继承和多态。

  • 面向对象的概念:面向对象是相对于面向过程而言的。面向对象和面向过程都是一种编程思想。学过C、C++语言的同学应该知道它们都是面向过程的语言,强调的是功能的行为。其实,java中的函数也是面向过程的,每个函数都实现了一个功能。我们学习的java语言是面向对象的语言,就是把很多功能进行封装,强调的是具备了功能的对象。既然对象封装了很多功能,每个功能都是一个函数,每个函数又都是面向过程的。那么面向对象也就是基于面向过程的。
  • 面向对象的特点
    • 是一种符合人们思考习惯的思想。
    • 可以将复杂的事情简单化。
    • 将程序员从执行者转换成了指挥者。
    • 在完成某个需求时,先要去找具有所需的功能的对象来用。如果该对象不存在,那么就创建一个具有所需的功能的对象。这样简化开发,并提高程序功能的复用性。
  • 面向对象的开发、设计
    • 面向对象的开发过程就是不断地创建对象,使用对象,指挥对象做事情。
    • 面向对象的设计过程就是管理和维护对象之间的关系。


封装就是隐藏对象的属性和内部功能的实现细节,仅提供公共的访问方式。
  • 封装的好处:将变化隔离;便于使用;提高重用性;提高安全性。
    以Student类举例,如果我们想要调用学生自我介绍的方法,我们可以创建一个学生对象,然后调用它的方法即可。
    代码:Student s=new Student();s1.print();
    这样便于使用,因为我们把学生自我介绍的内容都封装到了print()方法中,调用方法就等于学生自我介绍了。不同的类中都可以调用这个学生自我介绍的方法,这样也提高了代码的重用性。
    提高安全性是说如果我们想要给学生对象设置年龄,因为age属性是private修饰的,我们不能直接访问,可以调用setAge()方法,传个参数即可。如果我们传个非法的参数,比如将学生的年龄设置为-1,那么我们可以在这个setAge()方法中进行判断,过滤掉非法数据,这样就提高了程序的安全性。
  • 封装的原则:将不需要对外提供的内容都隐藏起来。把属性都隐藏,提供公共的方法对其访问。
    如下代码所示,学生的name和age属性都私有化了,提供了对外的set和get方法分别对其访问(可以快捷键shift + alt + s + r)。
    public class Student {    private String name;  //学生姓名    private int age;      //学生年龄      //获得姓名的方法    public String getName() {      return name;  }  //设置姓名的方法  public void setName(String name) {      this.name = name;  }  //获得年龄的方法  public int getAge() {      return age;  }  //设置年龄的方法  public void setAge(int age) {      this.age = age; }  //自我介绍的方法  public void print(){        System.out.println("自我介绍:我的姓名是:"+name+",年龄是:"+age);    }  } 




继承:多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。那个单独的类称为父类或者超类、基类,多个类称为子类。子类可以继承父类中除private修饰的属性和行为。比如现实生活中的猫、老虎都属于猫科动物,可以抽取出一个猫科动物类来描述猫和老虎的共性信息。父类还可以一级级的向上抽取,比如猫科动物类属于哺乳动物类,哺乳动物属于动物等。
在java中通过extends关键字让类与类之间产生继承关系。
  • 继承的好处
    • 继承的出现提高了代码的复用性。
      父类中定义了子类共性的内容,那么子类继承父类就相当于在子类中也拥有了这些内容,不用每个子类都再定义一遍了。
    • 继承的出现让类与类之间产生了关系,提供了多态的前提。
      继承是多态的基础,关于多态,在后面的博客中说明。
  • 继承的弊端:破坏了类的封装。因为父类中的数据可以被子类使用,而不再是只归父类自己使用,降低了程序的安全性。
  • 继承的特点
    • 在java只支持单继承,不支持多继承。
      一个类只能有一个父类,不可以有多个父类。
      因为多继承容易带来安全隐患:当多个父类中定义了相同的功能,而且功能的内容不同,那么子类对象不确定要运行哪一个。
      但是java保留这种机制,并用另一种体现形式来完成表示,那就是多实现。实现多个接口以扩展功能。
  • Java支持多层继承(继承体系)
    class A{}
    class B extends A{}
    class C extends B{}
  • 注意:不要仅为了获取其他类中某个功能而去继承,类与类之间要有所属" is a " 关系,子类是父类的一种。
    比如猫继承猫科动物,那么猫是猫科动物中的一种,这样符合现实生活中的逻辑。
    那么猫可以陪人玩耍,狗也可以陪人玩耍,让狗继承猫类,狗不就有这个功能了吗?但是,现实生活中,狗不是猫的一种,不符合逻辑。
  • 子类的实例化过程
    • 子类中所有的构造函数默认都会访问父类中空参数的构造函数。因为每一个构造函数的第一行都有一条默认的语句super();子类会具备父类中的数据,所以要先明确父类是如何对这些数据初始化的。
    • 当父类中没有空参数的构造函数时,子类的构造函数必须通过this或者super语句指定要访问的构造函数。

  • 抽象类:当多个类中出现相同功能(方法),但是功能的具体实现方式不同。这时可以进行向上抽取,只抽取功能定义,而不抽取功能主体,那么抽取出来的方法就是抽象方法。存在抽象方法的类就是抽象类。抽象类和抽象方法都用关键字abstract修饰。
  • 抽象类和一般类的区别:抽象类和一般类没有太大的区别,只不过,该事物出现了一些看不懂的、不确定的部分,但也是该事物的功能,需要明确出来。但是无法定义功能的具体实现方式,那么就通过抽象方法来表示。抽象类比一般类多了一个抽象方法。
  • 抽象类的特点:
    • 抽象类和抽象方法必须用abstract关键字来修饰。
    • 抽象方法只有方法声明,没有方法体,定义在抽象类中。
    • 格式:修饰符abstract返回值类型  函数名(参数列表);
    • 抽象类不可以被实例化,也就是不可以用new创建对象。因为抽象类是具体事物抽取出来的,本身是不具体的,没有对应的实例。而且抽象类即使创建了对象,调用抽象方法也没有意义。
    • 抽象类通过其子类实例化,而子类需要覆盖掉抽象类中所有的抽象方法后才可以创建对象,否则该子类也是抽象类。
    • 抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象。
  • 接口
    • 定义格式:interface 接口名称{}
    • 接口中的成员修饰符是固定的。
    • 成员常量:public static final(公共静态常量)
    • 成员函数:public abstract
    • 发现接口中的成员都是public的。
  • 接口的作用:
    • 接口的出现将“多继承”通过另一种形式体现出来,即“多实现”。
    • 子类可以实现多个接口,以便重写接口中的功能。
  • 接口的特点:
    • 接口是对外暴露的规则。
    • 接口是程序的功能扩展。
    • 接口的出现降低耦合性。
    • 接口可以用来多实现。
    • 类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口。
    • 接口与接口之间可以有继承关系。而且一个接口可以继承多个接口。
    • 接口与抽象类的共性:都是不断抽取出来的抽象的概念。
    • 接口与抽象类的区别:
      • 抽象类体现继承关系,一个类只能单继承;接口体现实现关系,一个类可以多实现。
      • 抽象类是继承,是 "is a "关系;接口是实现,是 "like a"关系。
      • 抽象类中可以定义非抽象方法,供子类直接使用;接口的方法都是抽象方法,接口中的成员都有固定修饰符,都是全局静态常量。

多态可以理解为事物存在的多种体现形态。
比如一个学生,你可以说他是一个人,还可以说他是一个男人或女人,还可以说他是学哪个专业的学生等等多种说法。

  • 多态的体现
    • 父类的引用指向了自己的子类对象。
      以Student类继承Person类举例说明:Person p=new Student();
    • 父类的引用也可以接收自己的子类对象。
      也就是说当一个方法的参数类型或者返回值类型是父类类型的话,子类对象都可以作为方法的参数或返回值传入或返回。
      比如Person类中有方法:goHome(Person p){}
      Student类调用Person类的goHome()方法:Person s1=new Student(); s1.goHome(s1);
  • 多态的前提
    • 必须是类与类之间有关系,要么继承,要么实现。
    • 通常还有一个前提:存在方法的覆盖
  • 多态的好处
    • 多态的出现大大提高了程序的扩展性。
    • 因为只要是有继承或实现关系,那么父类引用可以指向任何一个子类对象。
  • 多态的弊端:虽然提高了程序的扩展性,但是只能使用父类的引用访问父类中的成员。也就是说不可以访问子类中特有的成员。如果一定要访问子类中的特有成员,可以向下转型后访问。
  • 在多态中成员的特点
    • 在多态中成员变量的特点
    • 无论编译和运行,都参考左边(引用型变量所属的类)。
  • 在多态中非静态成员函数的特点
    • 在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有,编译失败。
    • 在运行时期:参阅对象所属的类中是否有调用的方法。如果没有,那么会调用引用型变量所属的类中相应的方法。
    • 简单一句话:成员函数在多态调用时,编译看左边,运行看右边。
  • 在多态中静态成员函数的特点:无论编译和运行,都参考左边。

注:参照了网上的一些内容。
0 0
原创粉丝点击