封装:
理解:当我们创建一个类的对象以后,我们需要对这个类里面的属性进行访问,对对象的属性进行赋值,从java语法的角度来说,我们除了受到属性的数据类型和存储范围的约束之外,没有其他限制,但是在实际问题上,我们还是需要对属性进行额外的限制条件,但是这个条件不能在属性声明的时候体现 ,我们就只能通过方法对属性进行限制条件的添加,此时就体现出了封装性的功能。
举个简单的例子,比如身份证号固定的18位,在赋值时就不能赋值非等于18位的数字或其他类型的值。
封装性的体现:我们将类的属性进行私有化,同时提供公共的方法来获取和设置此属性的值
封装性的体现需要权限修饰符来配合
java中有四种权限修饰符,public、缺省、protected、private
这四种权限修饰符可以用来修饰类及类的内部结构:属性、方法、构造器、内部类
修饰类的话只能用public或者缺省
总结:java提供了四种权限修饰符用来修饰类及类的内部结构,体现类及类的内部结构在被调用时的可见性的大小
方法的重载:在同一个类中可以有多个重名的方法存在,只要他们的参数个数、类型或顺序不同即可
判断是否是重载:两同一不同(同一个类、同一个方法名,不同的形参列表(数据类型、顺序、个数,满足一个即可))
跟方法的权限修饰符、返回值类型、变量名没有任何关系。
在对方法进行调用时,通过参数列表来确定。
总结:
重载是同一个类内允许多个同名的方法存在,但是他们的参数列表不同,编译器对于同名不同参数列表的方法进行了修饰,所以对于编译器而言,这些同名的方法就是不同的方法!他们的调用地址在编译期就被绑定了,java的重载是可以包括子类和父类的,也就是说子类可以重载父类中同名不同参数的方法。
所以对于重载而言,在方法调用之前,编译器就已经绑定了所要调用的方法,这种成为:早绑定或者说为静态绑定
方法的值传递机制:
形参:方法声明时的参数
实参:方法调用时,实际传给形参的参数值
总结:
如果变量是基本数据类型,则此时赋值的是变量所保存的数据值
如果变量是引用数据类型,则此时赋值的是变量索堡村的数据的地址值
可变个数形参的方法:数据类型...变量名
调用可变个数形参时,参数可以时0个也可以是多个,形参不同的方法之间构成了重载
可变个数形参的方法必须声明在末尾
可变个数形参在在方法的形参中,最多只能声明一个可变形参
this关键字的使用:当前对象(类的实例化),类的构造器中也可以使用
修饰属性和方法
在类的方法中,我们可以通过“this.属性”或“this.方法”来调用当前对象的方法和属性
this调用的构造器
在类的构造器中可以显式的使用“this(形参列表)”方式,调用本类中指定的其他构造器,但是不能调用自己
如果一个类中,有n个构造器,则最多有n-1个构造器使用了“this(形参列表)”,
注意点:在“this(形参列表)”必须在构造器中的首行,且最多只能声明一个
继承:
继承的好处:
①减少了代码的冗余,提高了代码的复用性
②便于功能的拓展,想要拓展的功能直接在父类中进行拓展,子类直接使用
③:为了之后多态性的使用,提供了前提
继承的格式:
class A extends B{}
A:子类、派生类、subclass
B父类、超生、基类、superclass
继承的体现:
一旦子类A继承了父类B之后,子类A将获取父类B中声明的所有的属性和方法
父类中声明的private的方法,子类继承父类后,仍然认为获取了父类中私有的结构
只是因为封装性的影响,无法直接调用父类中的私有的方法,需要通过访问设置器来进行获取
子类继承父类后,可以继续声明自己特有的属性和方法来实现功能的拓展
java中关于继承的一些规定
①一个类可以被多个子类继承
②一个类只能继承一个父类,java中的单继承性
③一个类可以派生出多个子类
④子父类是相对个概念,类是可以多层继承的,直接父类、间接父类
⑤子类继承父类后,就获取了父类以及间接父类中所有的声明的属性和方法
重写:
子类继承父类后,可以针对父类中的同名同参数的方法进行优化重写,进行覆盖操作
重写之后,当创建子类对象以后,通过子类对象调用子父类中同名同参数的方法时 ,实际执行的是子类中重写父类的方法
子父类中同名同参数的方法,子类中叫做重写的方法,父类中叫做被重写的方法
子类重写的父类的方法的方法名和参数需要和父类中被重写的方法和参数相同
子类重写的方法的权限修饰符不能小于父类被重写的方法的权限
父类被重写的方法的返回值类型是基本数据类型(double)则子类中重写的方法的返回值类型也需要是基本数据类型(需要也是double型)
super关键字,可以理解为:父类的
作用:可以用来调用属性、方法、构造器
我们可以在子类的方法或者构造器中,通过“super.属性”或“super.方法”的方式,显式的调用父类中声明的方法和属性
通常情况下可以省略super关键,但是在子父类中定义了重名的属性时,我们就必须要通过“”super.属性”的方式来调用父类的属性
同样的当想调用父类中被重写的方法时,也必须通过“super.方法”的方式来调用父类中被重写的方法
在构造器的首行的首行没有显式的声明“this(形参列表)”或“super(形参列表)”时,则默认调用的是父类中的空参构造器:super()
注意点:
我们在类的构造器中,针对“this(形参列表)”和“super(形参列表)”,二者只能存在一个
在类的多个构造器中,最少有一个构造器使用super(形参列表),来调用父类中的构造器
多态
可以理解为一个事物的多种形态,
前提:1、需要存在继承或者实现关系。2、有方法的重写
对象的多态性:父类的引用指向子类的对象(可以说:子类的对象赋给父类的引用)
对象的多态性只适用于对象的属性,不适应于对象的方法
java引用变量有两个类型:编译时类型和运行时类型。编译时类型有声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。简称:编译时,看左边;运行时,看右边
(编译时:要查看引用变量所声明的类中是否有所调用的方法
运行时:调用实际new的对象所属类中的重写方法)
而编译时类型和运行时类型不一致,就出现了对象的多态性
Person p = new Student();
Object o = new Person();//Object类型的变量o,指向Person类型的对象
o = new Student(); //Object类型的变量o,指向Student类型的对象
1、
一个引用类型变量如果声明时为父类的类型,但实际引用的是子类的对象,那么该变量,那么该变量就就不能在访问子类中添加的方法或者属性
Student m = new Student();
m.school = “pku”; //合法,Student类有school成员变量
Person e = new Student();
e.school = “pku”; //非法,Person类没有school成员变量
属性是编译时确定的,而编译时e是Person类型,而Person类型中没有school成员变量,所以编译错误
2、方法声明时的形参类型为父类的类型时,可以使用子类的对象作为实参调用该方法
public class Test {
public void method(Person e) {
// ……
e.getInfo();
}
public static void main(Stirng args[]) {
Test t = new Test();
Student m = new Student();
t.method(m); // 子类的对象m传送给父类类型的参数e } }
3、虚拟调用方法
正确的方法调用:
Person e = new Person();
e.getInfo();
Student e = new Student();
e.getInfo();
虚拟方法调用(多态情况下)
子类中定义了与父类同名同参数的方法,在多态情况下,将此时父类中的同名同参数的方法称为虚拟方法,父类通过赋给他的不同子类对象,动态调用属于子类的该方法,这样的方法调用在编译期是无法确定的
Person e = new Person();
e.getInfo();
Student e = new Student();
e.getInfo();
编译时e为Person类型,而方法的调用是在运行时确定的,所以调用的是Student类中的getInfo方法,这种属于动态绑定
总结:
对于多态而言:只有等到方法调用的那一刻,解释运行器才会确定所要调用的具体方法,这也被成为:晚绑定或动态绑定