1.封装
一、封装与隐藏
-
问题的引入:当我们创建一个类的对象以后,我们可以通过“对象.属性”的方式,对对象的属性进行赋值。这里,赋值操作要受到属性的数据类型的存储范围的制约。但是除此之外,没有其他制约条件。但是在实际问题中,我们往往需要给属性赋值加入额外的限制条件。这个条件就不能再属性声明时体现,我们只能通过方法进行限制条件的添加。(比如:setLegs())。同时,我们需要避免用户使用“对象.属性”的方式对属性进行赋值。则需要将声明为私有的(private)
-
此时,针对属性就体现了封装性
二、封装性的体现:
1.我们将类的属性XXX私有化(private),同时,提供公共的(public)方法来获取(getXXX)和设置此属性 的值
例:
private legs; public int getLegs(){ return legs; }
2.不对外暴露的私有的方法
三、封装性的体现,需要权限修饰符来配合
-
Java规定的4中权限(从小到大排列):private、缺省(什么都不写就为缺省权限)、portected、public
-
4种权限可以用来修饰类及类的内部结构:属性、方法、构造器、内部类
-
具体的,4种权限都可以用来修饰类的内部结构:属性、方法、构造器、内部类
-
修饰类的话,只能使用缺省、public
-
修饰符 | 类内部 | 同一个包 | 不同包的子类 | 同一个工程 |
---|---|---|---|---|
private | yes | |||
(缺省) | yes | yes | ||
protected | yes | yes | yse | |
public | yes | yes | yes | yes |
总结:Java提供了4种权限修饰符来修饰类及类的内部结构,体现类及类的内部结构再被调用时的可见性的大小。
2.构造器
一、构造器的特征
-
它具有与类相同的名称
-
它不声明放回值类型(与声明为void不同)
-
不能被static、final、synchronized、abstract、native修饰,不能有return语句的返回值
二、构造器的作用:
-
创建对象;给对象进行初始化
-
初始化对象的信息
Person p=new Persion() //创建类的对象:new + 构造器
三、说明
-
如果没有显示的定义类的构造器的话,则系统默认提供一个空参的构造器
-
定义构造器的格式:权限修饰符 类名(形参列表){}
-
一个了剋种定义的多个构造器,彼此构成重载
-
一旦我们显示的定义了类的构造器之后,系统就不再提供默认的空参构造器
-
一个类中,至少要有一个构造器
3.属性的赋值过程
-
默认初始化值
-
显示初始化值
-
构造器中赋值
-
通过“对象.方法”或“对象.属性”的方式,赋值
以上操作的先后顺序为:1-2-3-4
4.JavaBean
-
JavaBean是一种Java语言写成的可重用组件
-
所谓JavaBean,是指符合如下标准的Java类
-
类是公共的
-
有一个无参的公共的构造器
-
有属性,且有对应的get、set方法
-
-
用户可以使用JavaBean将功能、处理、值、数据库访问和其他任何可以用Java代码创造的对象进行打包,并且其他的开发者可以通过内部的JSP页面、Servlet、其他JavaBean、applet程序或者应用来使用这些对象。用户可以认为JavaBean提供了一种随时随地的复制和粘贴的功能,而不用关心任何改变。
5.关键字
this的使用
-
this可以用来修饰:属性、方法、构造器
-
this修饰属性和方法:
-
this理解为:当前对象或当前正在创建的对象
//在类的方法中,我们可以使用“this.属性”或“this.方法”的方式,调用当前对象属性或方法。但是,通常情况下,我们都选择省略“this.”。特殊情况下,如果方法的形参和类的属性同名时,我们必须显示的使用“this.变量”的方式,表明此变量是属性,而非形参。 //例: Class Person{ private String name; private int age; public void setName(String name){ this.name=name; } public void setAge(int age){ this.age=age; } }
-
-
this调用构造器
-
我们在类的构造器中,可以显示的使用“this(形参列表)”方式,调用本类中指定的其他构造器
-
构造器中不能通过“this(形参列表)”方式调用自己
-
如果一个类中有n个构造器,则最多有n-1构造器中使用了“this(形参列表)”
-
规定:“this(形参列表)”必须声明在当前构造器的首行
-
构造器内部,最多只能声明一个“this(形参列表)”,用来调用其他的构造器
-
super关键字
-
super理解为:父类的
-
super可以用来调用:属性、方法、构造器
-
super的使用
-
我们可以在子类的方法或构造器中。通过使用”super.属性“或"super.方法"的方式,显示的调用父类中声明的属性或方法。但是,通常情况下,我们习惯省略”super.“
-
特殊情况下:当子类和父类中定义了同名的属性时,我们想要在子类中调用父类中声明的属性,则必须显示的使用“super.属性”的方式,表明调用的时父类中声明的属性
-
当子类重写了父类中的方法以后,我们想在子类的方法中调用父类中被重写的方法时,则必须显示的使用“super.方法”的方式,表明调用的是父类中被重写的放法
-
-
super调用构造器
-
我们可以在子类的构造器中显示的使用“super(形参列表)”的方式,调用父类中声明的指定的构造器
-
“super(形参列表)”的使用,必须声明在子类构造器的首行
-
我们在类的构造器中,针对于“this(形参列表)”或“super(形参列表)”只能二选一,不能同时出现
-
在构造器的首行,没有显示的声明“this(形参列表)”或“super(形参列表)”,则默认调用的是父类中的空参构造器:”super()“
-
在类的多个构造器中,至少有一个类的构造器使用了“super(形参列表)”,调用父类中的构造器
-
package的使用
-
为了更好的实现项目中类的管理,提供包的概念
-
使用package声明类或接口所属的包,声明在源文件的首行
-
包,属于标识符,遵循标识符的命名规则、规范(xxxxyyyyzzzz)、“见名知意”
-
每“.”一次,就代表一层文件目录
注意:同一个包下,不能命名同名的接口、类。不同的包下,可以命名同名的接口、类
JDK中主要的包介绍
-
java.lang---包含一些Java语言的核心类,如String、Math、Integer、System和Thread,提供常用功能
-
Java.net----包含执行与网络相关的操作的类和接口
-
Java.io---包含能提供多种输入/输出功能的类
-
java.util---包含一些实用工具类,如定义系统特性、接口的集合框架、使用与日期日历相关的函数
-
java.text---包含一些Java格式化相关的类
-
Java.sql---包含了Java进行JDBC数据库编程的相关类/接口
-
Java.awt---包含了构成抽象窗口工具集(abstract window toolkits)的多个类,这些类被用来构建和管理应用程序的图形用户界面(GUI)
import:导入
-
在源文件中显示的使用import结构导入指定包下的类、接口
-
声明在包的声明和类的声明之间
-
如果需要导入多个结构,则并列写出即可
-
也可以使用“xxx.*”的方式,表示可以导入xxx包下的所有结构
-
如果使用的类或接口是Java.lang包下定义的,则可以省略import结构
-
如果使用的类或接口,是本包下定义的则也可以省略import结构
-
如果在源文件中使用了不同报下的同名的类,则必须至少有一个类需要以全类名的方式显示
-
使用“xxx.*”方式表明可以调用xxx包下的所有结构、但是如果使用的是xxx子包下的机构,则仍需要显示导入
-
import static:导入指定类的接口中的静态结构:属性或方法
instanceof关键字的使用(向下转型使用)
-
使用情景:为了避免在向下转型时出现ClassCastException的异常,我们在向下转型之前,先进行instanceof的判断,一旦返回true,就进行向下转型。如果返回false,不进行向下转型。
-
如果 a instanceof A返回true,则a instanceof B也返回true,其中类B是类A的父类
6.继承性
一、继承性的好处:
-
减少了代码的冗余,提高了代码的复用性
-
便于功能的扩展
-
为之后多态性的使用,提供了前提
二、继承性的格式:Class A extends B{}
-
A:子类、派生类、subclass
-
B:父类、超类、、基类、superclass
-
体现:一旦子类A继承父类B以后,子类A中就获取了父类B中声明的所有属性、方法(父类中声明为private的属性或方法,子类继承父类以后,任然认为获取了父类中私有的结构。只是因为封装性的影响,使得子类不能直接调用父类的结构而已)
-
子类继承父类以后,可以声明自己特有的属性或方法:实现功能的拓展。子类和父类的关系,不同于子集和集合的关系
三、Java中关于继承性的规定
-
Java只支持单继承和多层继承,不允许多重继承
-
一个类可以被多个子类继承
-
Java中类的单继承性:一个类只能有一个父类
-
子父类是相对的概念。
-
子类直接继承的父类,称为:直接父类。间接继承的父类称为:间接父类
-
子类继承父类以后,就获取了直接父类以及所有简介父类中声明的属性和方法
-
四、Object初始父类
-
如果我们没有显示的声明一个类的父类的话,则此类继承于Java.lang.Object类
-
所有的Java类(除了Java.lang.object类之外)都直接互简介的继承于java.lang.Object类
-
意味着,所有的Java类具有Java.lang.Object类声明的功能
7.方法的重写
-
定义:在子类中可以根据需要对从父类中继承来的方法进行改造,也称为方法的重置、覆盖。在程序执行时,子类的方法将覆盖父类的方法
-
注意:子类于父类中同名同参的方法必须同时声明为非static的(即为重写),或者同时声明为static的(不是重写)因为static方法是属于静态类的,子类无法覆盖父类的方法
-
重写的规定:
-
子类重写的方法的方法名和形参列表于父类被重写的方法的方法名和形参列表相同
-
子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符
-
特殊情况:子类不能重写父类中声明为private权限的方法
-
-
返回值类型:
-
父类被重写的方法的返回值类型是void,则子类重写的方法的返回值类型只能是void
-
父类被重写的方法的返回值类型是A类型,则子类重写的方法的返回值类型可以是A类或A类的子类
-
父类被重写的方法的返回值类型是基本数据类型(比如:double),则子类重写的方法的返回值类型必须是相同的基本数类型(必须也是doble类型)
-
-
子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型
-
8.子类对象实例化过程
-
从结果上来看(继承性)
-
子类继承父类以后,就获取了父类中声明的属性或方法
-
创建子类的对象,在堆空间中,就会加载所有父类中声明的属性
-
-
从过程上来看:
-
当我们通过子类的构造器创建子类对象时,我们一定会直接或间接的调用其父类的构造器,进而调用父类的父类的构造器,直到调用了Java.lang.Object类中空参的构造器为止。正因为加载过所有父类的结构,所以才可以看到内存中有父类中的结构,子类对象才可以考虑调用
-
明确:虽然创建子类对象时,调用了父类构造器,但是自始自终就创建过一个对象,即为new的子类对象
9.多态性
-
理解多态性:可以理解为一个事务的多种形态
-
什么是多态性:
-
对象的多态性:父类的引用指向子类的对象(或子类的对象赋给父类的引用)
-
-
多态的使用:虚拟方法调用
-
有了对象的多态性以后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父类的方法
-
虚拟方法的定义:子类中定义了与父类同名同参数的方法,在多态情况下,将此时父类的方法称为虚拟方法,父类根据赋给它不同的子类对象,动态调用属于子类的方法。这样的方法嗲用在编译期时无法去确定的
-
-
多态性的使用前提:
-
类的继承关系
-
方法的重写
-
-
对象的多态性,只适用于方法,不适用于属性
总结:编译,看左边,执行,看右边
10.Object类的使用
-
Object类是所有Java类的根父类
-
如果在类的声明中未使用extends关键字指明其父类,则默认父类为java.lang.Object类
-
Object类中的功能(属性、方法)就具有通用性
-
属性:五
-
方法:equals()、toString()、getClass()、hashCode()、clone()、finalize()、wait()、notify()、notifyAll()
-
-
Object类只声明了一个空参构造器
equals()方法的使用
-
是一个方法,而非运算符
-
只能适用于引用数据类型
-
Object类中equals()的定义:Object类中定义的equals()和==的作用是相同的,比较两个对象的地址值是否相同,即两个引用是否指向同一个对象实体
-
像String()、Date()、File()、包装类等都重写了Object类中的equals()方法。重写以后,比较的不是两个引用的地址是否相同,而是比较两个对象的“实体内容”是否相同