Java面向对象三大特征——封装继承多态

Java面向对象
  • class和instance是“模板”和“实例”的关系
  • class是数据类型,instance是数据
  • class定义了field(字段),每个instance(实例)都会拥有各自的field
  • 变量指向instance(实例),并通过变量.字段名访问field
  • 指向instance(实例)的变量都是引用变量

一、

封装:将属性私有化,提供公有的方法访问私有属性
  • 一个class可以包含多个field
  • 直接把field用public暴露给外部可能破坏了封装
  • 用private修饰field可以拒绝外部访问
  • 定义public方法(setXxx和getXxx)可以间接修改field

  • 外部代码通过调用public方法间接设置和获取private字段
  • public方法封装了数据访问
  • 通过方法访问实例字段更安全
  • 通过变量.方法名()来调用实例方法 s.setName("pony");
    方法内部可以使用隐式变量this:
  • this指向当前实例
  • this.field可以访问当前实例的字段
构造方法
  • 构造方法可以创建实例时初始化对象实例
  • 构造方法名就是类名
  • 构造方法的参数没有限制
  • 构造方法没有返回值(也没有void)
  • 必须用new操作符调用构造方法
  • 初始化顺序:
    • 先初始化字段
    • 没有赋值的字段初始化为默认值:基本类型=0,引用类型=null
    • 再执行构造方法的代码

  • 一个构造方法可以调用其他构造方法,便于代码复用
  • 调用其他构造方法的语法是this(实参。。。)

方法重载(Overload):
  • 多个方法的方法名相同
  • 但各自的参数不同。参数个数、参数类型、参数位置不同
  • 方法返回值类型通常都是相同的
  • 目的:
    • 相同功能的方法使用同一名字
    • 便于调用
  • 重载主要依靠参数类型和数量区分,不要交换参数顺序
  • 重载方法应该完成相同的功能

1、什么是封装?

封装就是将属性私有化,提供公有的方法访问私有属性。

做法就是:修改属性的可见性来限制对属性的访问,并为每个属性创建一对取值(getter)方法和赋值(setter)方法,用于对这些属性的访问。

如:private String name;

public String getName(){

                    return;

           }

        public void setName(String name){

                    this.name=name;

           }

2、  为什么需要封装?

通过封装,可以实现对属性的数据访问限制,同时增加了程序的可维护性。

由于取值方法和赋值方法隐藏了实现的变更,因此并不会影响读取或修改该属性的类,避免了大规模的修改,程序的可维护性增强。

3、  this关键字是什么意思?

有时一个方法需要引用调用它的对象。为此,java定义了this这个关键字。简单地说,

This是在对象内部指代自身的引用。可以直接引用对象,可以解决实例变量和局部变量之间发生的任何同名的冲突。

4、  如何实现封装,实现封装的具体方法?

1)、修改属性的可见性来限制对属性的访问。

2)、为每个属性创建一对赋值方法和取值方法,用于对这些属性的访问。

3)、在赋值和取值方法中,加入对属性的存取的限制。

5、什么是构造方法?构造方法的语法规则?

         构造方法负责对象成员的初始化工作,为实例变量赋予合适的初始值。

构造方法的语法规则:方法名与类名相同。没有返回类型。

使用new关键字实例化对象的过程实际上就是调用构造方法的过程。或者说实例化一个对象实际上就是去调用这个对象的构造方法。

Xin xin=new Xin();

在实例化对象的时候,已经实例变量赋予了初始值,完成了对象的初始化工作。

6、  为什么需要构造方法?

为属性赋值时,很容易忘记对其中的一项或多项进行赋值。构造方法可以简化对象初始化,为实例变量赋值。

7、  带参数的构造方法:可以显示地为实例变量赋予初始值。在不同的条件下创建不同的对象,这些对象的实例变量具有不同的值。

注意:在使用带参数的构造方法实例化对象时,传递的值和构造方法的参数应当在个数、次序和数据类型上相互配备。

通过调用带参数的构造方法,在创建对象时,一并完成了对象的初始化工作,简化了对象初始化的代码。

8、  什么是方法重载?

方法名称相同,参数项不相同。那么认为一个方法是另一个方法的重载方法。

注意:重载只跟参数有关,与返回类型无关。方法名和参数相同而返回类型不相同,不能说是重载。

典型的方法重载:System.out.println();  Sysstem.out代表了一个java.io.PrintSteam对象,具有多个println(打印)方法,该方法可以接收不同类型的数据作为参数根据类型不同,

调用不同的打印方法。

java.lang包中的Math类中的max方法。

Public static int max(int a,intb);

Public static int max(long a,long b);

Public static int max(float a,float b);

Public static int max(double a,double b);

在调用方法之前,java虚拟机先判断给定的类型,然后决定到底调用执行那个max()方法。

9、  什么是构造方法重载?

构造方法重载是方法重载的一个典型的特例。参数列表不同。

可以通过重载构造方法来表达对象的各种多种初始化行为。也就是说在通过new语句创建一个对象时,可以实现在不同的条件下,让不同的对象具有不同的初始化行为。

Private String name;

Private String sex;

Public Xin(String name){

 this.name=name;

}

Public Xin(String name,String sex){

           this.name=name;

           this.sex=sex;

}

二、

继承:是面向对象编程的一种代码复用方式,使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。

  • 子类拥有父类的所有功能,子类可以编写新增功能
  • 只允许继承自一个类(单继承)
  • 一个类有且仅有一个父类
    • 父类定义的private字段无法被子类访问
    • 用protected修饰的字段可以被子类访问
  • super
    • super关键字表示父类(超类)
    • 构造方法的第一行语句必须调用super()
    • 没有super()时编译器会自动生成super()
    • 如果父类没有默认构造方法,子类就必须显示调用super()
    • 子类的构造方法可以通过super()调用父类的构造方法
  • 向上转型
    • 可以安全地向上转型为更抽象的类型
    • 向上转型把一个子类型安全地变为更加抽象的类型
    • Person p = new Person();
    • Student s = new Student();
    • Person ps = new Student();  //upcasting
    • Object o1 = p; //upcasting
    • Object o2 = s; //upcasting     默认继承自Object类
  • 向下转型
    • 把抽象的类型变成一个具体的子类型
    • 可能报错ClassCastException
    • 可以强制向下转型,最好借助instanceof判断
    • Person p = new Student();  //upcasting
    • Student s = (Student) p;   //downcasting
  • instanceof操作符可以判断对象的类型
    • Person p = new Person();
    • System.out.println(p instanceof Person);  //true
    • System.out.println(p instanceof student); //false
    • Student s = new Student();
    • System.out.println(s instanceof Person);  //true
    • System.out.println(s instanceof student);  //true
  • 子类和父类的关系是is,has关系不能继承


继承存在如下缺陷:

         1、父类变,子类就必须变

         2、继承破坏了封装,对于父类而言,它的实现细节对与子类来说都是透明的

         3、继承是一种强耦合关系     

      所以说当我们使用继承的时候,我们需要确信使用继承确实是有效可行的办法。那么到底要不要使用继承呢?《Think in java》中提供了解决办法:问一问自己是否需要从子类向父类进行向上转型。如果必须向上转型,则继承是必要的,但是如果不需要,则应当好好考虑自己是否需要继承


三、

重写(Override)——子类覆写父类的方法 (返回值、参数相同)

  • 加上@Override可以让编译器帮助检查是否进行了正确的覆写
  • 方法签名如果不同(参数不同)就不是Override,而是创建了一个新方法
  • @Override不是必需的
 
public class Person {
    public void run() {...}
}
public class Student extends Person {
    @Override
    public void run() {...}
}
Person p = new Student();
p.run();  //调用的是实际类型Student的run();
引用变量的声明类型可能与其实际类型不符实例对象的方法调用总是对应实际类型Java的实例方法调用是基于运行时实际类型的动态调用

多态:是指针对某个类型的方法调用,其真正执行的方法取决于运行时期实际类型的方法(Java的方法调用总是作用于对象的实际类型)。即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性
  • 对某个类型调用某个方法,执行的方法可能是某个子类的覆写方法
  • 利用多态,允许添加更多类型的子类实现功能扩展

Object定义的几个重要方法:
  • toString:把instance输出为String
  • equals:判断两个instance是否逻辑相等
  • hashCode:计算一个instance的哈希值 
super
  • super可以调用父类的被Override的方法。super.父类方法名()
final
  • final修饰的方法不能被重写Override
  • final修饰的类不能被继承
  • final修饰的字段在初始化后不能被修改


  Java实现多态有三个必要条件:继承、重写、向上转型。

  • 继承:在多态中必须存在有继承关系的子类和父类。
  • 重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。
  • 向上转型:在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够具备技能调用父类的方法和子类的方法。



你可能感兴趣的:(java基础)