封装
封装的思想:隐藏实现的细节,提供访问入口。
封装的体现:
属性的封装-----私有成员变量,提供get和set方法。
功能的封装------在类中封装方法,方便功能复用。
封装作用:提高代码的安全性和复用性。
继承
定义:继承是将多个类的相同属性和行为抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承单独这个类即可使用这些属性和行为了,多个类称为子类(派生类),单独的这个类称为父类(基类 或超类)。
作用是: 减少了代码冗余,提高了代码的复用性,有利于子类功能的扩展。
Java类只支持单继承,不支持多继承!但支持多层继承!
所谓多层继承就是子类A继承父类B ,B又继承了父类C,相当于A间接多层继承了C。
一个类可以具有多个子类,但只能有一个父类。
在子类中访问成员变量的特点
在子类方法中访问一个变量满足:就近原则
先找子类方法内的局部变量-----然后找子类成员变量-----最后找父类成员变量
【也可以通过super关键字,直接指定访问父类的成员变量。super.父类成员变量】
在子类中访问成员方法的特点
如果父类和子类中,出现了相同的成员方法,也会优先使用子类的,如果一定要使用父类的方法,也是使用super关键字。
super.父类成员方法( );
Question:
1、子类是否可以继承父类的私有成员?
可以继承,但是子类不能直接访问。父类私有成员只能在本类中使用。
2、子类是否可以继承父类的构造方法?
不可以。构造方法名必须和类名相同,如果子类可以继承父类构造方法,将和语法规定产生矛盾。
子类创建对象的特点
特点:子类对象创建时,默认先执行父类的无参构造方法。
原理:在子类的所有构造方法的第一行,默认有super(),表示调用父类的无参构造方法。
Question:
如果父类中没有无参构造器,会出现什么现象呢?
会报错。因为子类默认是调用父类无参构造器的。
如何解决?
子类可以调用父类带参构造器来初始化父类的数据。
格式:在子类构造器第一行,添加 super(参数) 代码。
注意:只能在子类构造方法的第一行去调用父类构造方法。
【这里再多加一个知识点对于静态代码块和静态属性、普通代码块和普通属性及构造方法在子父类调用的顺序】
类成分由5大成分构成:成员变量、成员方法、构造方法、代码块、内部类。
成员变量:描述类或者对象的属性信息;如:性别,年龄。
成员方法:描述类或者对象的行为特征;如:唱歌,吃饭,买票。
构造方法:初始化一个类的对象返回。
代码块:类似方法,但和方法不同,它没有方法名,没有返回值,没有参数,只有{}包起来的方法体,而且不用通过对象或类显示调用,而是在加载类的时候或者创建对象的时候隐式调用。修饰符可以选但只能写static【使用static的叫静态代码块,对类进行初始化,它随着类的加载进行初始化,并且只执行一次。没static的叫普通代码块,每次创建一个对象就执行一次,也就是需要new对象时才会被调用而且是每次创建新对象就会被调用。】代码块是对构造器功能的一种补充,如果多个构造器中都有重复的语句,就可以提到代码块中,提高代码的复用性。【代码块的调用是优先于构造器的】
内部类:指在一个外部类的内部再定义一个类,内部类可为静态,可用protected和private修饰,而外部类只能使用public和缺省的包访问权限,内部类主要由成员内部类、局部内部类、静态内部类、匿名内部类。
存在继承关系时调用的顺序:
- 父类的静态代码块和静态属性(优先级一样,谁在前面就先调用,例如如果静态方法在静态代码块前面就先调用静态方法)
- 子类的静态代码块和静态属性(优先级一样)
- 父类的普通代码块和普通属性初始化
- 父类的构造方法
- 子类的普通代码块和普通属性初始化
- 子类的构造方法
多态
定义:多态是同一个行为具有多种不同表现形式。
多态的前提:
- 有继承/实现关系。
- 有方法重写。
- 有父类引用指向子类对象。(或者接口指向实现类对象)
多态中成员访问特点:
方法调用:编译看左边(父类),运行看右边(子类)
Animal a = new Cat();
对象 a 能调用什么方法,由对象a 左边 的父类 Animal 决定。
方法运行起来的效果,由对象a 右边 new出来的子类 Cat决定。
变量调用:编译看左边(父类),运行也看左边(父类)。
结论:多态是方法的多态,变量没有多态性的!
多态的优缺点:
多态优点:
- 提高代码的扩展性。
- 定义方法时,如果将父类或 接口作为参数,在调用方法时,可以传递任意子类对象极大提高方法的通用性。
多态缺点:多态下不能使用子类的特有功能,就需要先用 instanceof 关键字进行类型判断判断类型然后再向下转型强转后才能调用。
格式:对象 instanceof 类
向上转型:子类到父类(自动类型转换)
举例:
Dog dog = new Dog();
Animal a = dog; //向上转型
向下转型:父类到子类(强制类型转换)
举例:
Animal a = new Dog();
子类 对象名 = (子类)父类引用;
Dog dog = (Dog)a; //向下转型
如果父类引用的 实际类型 与要转换的 目标类型 不同,就会出现类型转换异常:ClassCastException
举例:
Animal a = new Cat();
Dog dog = (Dog)a; //会发生类型转换异常