01.面向对象
1.1理解面向对象
面向过程:强调的是功能行为,考虑如何去做
面向对象:强调的是功能的对象,考虑谁来做
举例:人把大象装冰箱
1.2面向对象的两个概念
类:对一类事物的描述,是抽象概念上的定义
对象:实际存在的某一类的实体
举例:类=抽象概念的人,对象:一个真实存在的人
两者关系:对象是由类所new出来的,对象是类的实例化
1.3面向对象的三部分
1.Java类及类的成员:属性、方法、构造器、代码块、内部类
2.面向对象的三大特征:封装性、继承性、多态性
3.一些关键字:this、super、static、final、abstract、interface、package、import
02.类和类的对象
面向对象的重点就是类的设计,设计类就是设计类的成员。
2.1 Java类及类的成员
拿人类举例:人类有自己的名字、年龄、身高这些属性,还有吃饭、睡觉、玩耍这些行为。
常见的类的成员: 属性=成员变量=域=field 方法=成员方法=函数=method
2.2 类与对象的创建和使用
public class PersonTest{
public static void main(String[] args){
//创建Person类的对象
//创建语法:类名 对象名 = new 类名();
Person p1 = new Person();
//调用类的结构:属性、方法
p1.name = "Tom";
p1.age = 25;
p1.isMarried = true;
System.out.println(p1.name);
//调用方法:"对象.方法"
p1.eat();
p1.sleep();
p1.talk("Chinese");
//------------创建第二个对象
Person p2 = new Person();
System.out.println(p2.name); //初始化值为null
System.out.println(p2.isMarried);
//---------将p1变量保存的对象地址赋给p3,导致p1和p3指向堆中同一对象实体
Person p3 = p1;
System.out.println(p3.name);
p3.age = 10;
System.out.println(p1.age)
}
}
//创建Person类
class Person{
//属性
String name;
int age;
boolean isMarried;
//方法
public void eat(){
System.out.println("吃饭");
}
public void sleep(){
System.out.println("睡觉");
}
public void talk(String language){
System.out.println("人可以说话,使用的是: " + language);
}
}
2.3 对象的内存解析
栈:把局部变量存储在栈结构中
堆:把new出来的比如对象、数组存储在堆空间中
2.4匿名对象
匿名对象的理解:在创建对象时,没赋值给一个变量名,就是匿名对象
特点:匿名对象只能使用一次
举例子:
new Person().eat();
new Person().walk();
new Person.age = 25;
new Person.showname();
03类的成员之一:属性
属性和局部变量的对比
1.相同点: 格式:数据类型 变量名 = 变量值 。都是先声明后使用。都有对应的作用域。
2.不同点:
2.1声明的位置不同:
属性直接声明在类的{}中 局部变量:声明在方法内、方法形参、构造
器内、构造器形参
2.2 权限修饰符不同:
属性可以指定权限修饰符:private public 缺省 protected
局部变量不可以使用权限修饰符
2.3初始化类型
属性有初始化类型。局部变量没有初始化类型,在调用局部变量之前一定要显式赋值
2.4在内存中加载的位置不同:
属性:加载到堆空间中。局部变量加载到栈空间中。
public class UserTest{
public static void main(String[] args){
User u1 = new User();
System.out.println(u1.name);
System.out.println(u1.age);
System.out.println(u1.isMarried);
u1.talk("俄语");
}
}
public User{
//属性
String name;//如果不加public,就是缺省
public int age;
boolean isMarried;//是否结婚了
public void talk(String language){ //language是形参,也就是局部变量
System.out.println("我们使用的是" + language + "language");
}
public void eat(){
String food = "石头饼"; //局部变量
System.out.println("北方人爱吃: " + food);
}
}
04属性的成员之二:方法
方法:描述类具有的功能
4.1方法声明
权限修饰符 返回值类型 方法名(形参列表){
方法体;
}
比如
public void eat(String name){
System.out.println("今天中午吃:" + name);
}
4.2方法定义说明
权限修饰符四种:public private 缺省 protected
关于返回值类型:
如果方法有返回值,则需要在方法声明时,指定返回值的类型。并且必须在方法中使用return关键字
来返回指定类型的数据。格式为"return 数据"
如果方法没有返回值类型,则在方法声明时,使用void表示。void方法通常不用return。(根据需要)
方法名要符合标识符命名规范,还要做到见名知意。
形参列表:可以声明任意个形参 。声明多个形参格式为 数据类型1 形参1 数据类型2 形参2,....
方法体内写想要用此方法实现的操作
特殊的 方法中不可以定义方法
4.3方法的重载(overload)
方法重载的概念:在同一个类中,允许存在一个以上同名方法,只要它们的参数个数或参数类型不同。
总结:"两同一不同",同一个类、相同方法名 参数列表不同(参数个数,参数类型不同)
构成重载的举例:
如何确定调用的是类的哪一个方法?可以根据方法名字和方法形参的个数来确定
4.4方法参数的值传递机制
1.变量赋值的举例
//基本数据类型
int m = 10;
int n = m;
System.out.println("m=" + m + ", n=" + n);
//引用数据类型
Order o1 = new Order();
o1.orderId = 42;
Order o2 = o1;//此时,赋值以后,o1和o2指向堆空间中同一个对象实体
System.out.println("o1.orderId =" + o1.orderId + ",o2.orderId=" + o2.orderId);
规则:如果变量是基本数据类型,此时赋值的是变量所保存的数据值
如果变量是引用数据类型,此时赋值的是变量所保存的地址值
2.形参和实参段的概念:
形参:方法定义时,声明的小括号内的参数
实参:方法调用时,实际传递给形参的数据
3.java中参数传递机制:值传递
规则:如果参数是基本数据类型,此时实参赋给形参的是实参真实存储的数据
如果参数是引用数据类型,此时实参赋给形参的是所保存数据的地址值
例一:
public class ChangeTest {
public static void main(String[] args) {
int m = 10;
int n = 20;
swap(m,n);
System.out.println(m +"," + n);
}
public static void swap(int m,int n) {
int temp = m;
m = n;
n = temp;
System.out.println(m + "," + n);
}
}
例二:
class Data{
int m;
int n;
}
public class ChangeTest{
public static void main(String[] args) {
Data data = new Data();
data.m = 10;
data.n =20;
swap(data);
System.out.println(data.m + "," + data.n);
}
public static void swap(Data data) {
int temp = data.m;
data.m = data.n;
data.n = temp;
}
}
05面向对象的特征一:封装和隐藏
5.1.为什么要引入封装?
我们在使用一个东西时,有时候只要知道怎么去用它就好,不用了解它内部的结构。
程序追求高内聚低耦合。高内聚:类的内部数据操作由自己完成,不许外部干涉。
低耦合:仅对外暴露少量的方法用来使用
隐藏对象内部的复杂性,对外公开简单的接口
就是把该隐藏的隐藏,该暴露的暴露出来
5.2.封装思想具体的代码实现:
体现一:将类的属性xxx私化(private),同时,提供公共的(public)方法来获取(getXxx)和设置(setXxx)此属性的值
private int age;
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
体现二:不对外暴露的私有方法
体现三:单例模式(将构造器私有化)
体现四:不想让一个类在包外被调用,可以将此类定义为缺省的
5.3Java规定的四种权限修饰符
4种权限都可以用来修饰类的内部结构:属性、方法、构造器、内部类
修饰类的话,只能使用:缺省、public
06构造器(构造方法) Constructor
6.1构造器的作用
1.创建对象 2.初始化对象的信息
6.2构造器的使用说明
1.如果没有显式定义构造器的话,系统默认会提供一个空参构造器
2.格式: 权限修饰符 类名(形参列表){}
3.一个类中多个构造器,彼此构成重载
4. 一旦显式的定义了类的构造器后,系统不再提供默认的空参构造器
5.一个类至少有一个构造器
举例
public Person(){
System.out.println("1");
}
public Person(String name){
name = n;
}
public Person(String n ,int a){
name = n;
age = a;
}
6.3总结属性赋值的先后顺序
1.默认初始化值 2.显式初始化 3.构造器中初始化 4.通过"对象.方法"或"对象.属性"赋值
6.4JavaBean的概念
所谓JavaBean,是指符合如下标准的Java类:
>类是公共的
>一个无参的公共的构造器
>属性,且对应的get、set方法
07this关键字的使用
7.1this关键字用来修饰、调用属性、方法、构造器
7.2this可以理解为当前对象
7.3在类的方法中,我们可以使用"this.属性"或"this.方法"的方式,调用当前对象属性和方法。
通常情况下,我们都选择省略“this.”。特殊情况下,如果方法的形参和类的属性同名,我们必须显式 * 的使用"this.变量"的方式,表明此变量是属性,而非形参。
7.4在类的构造器中,我们可以使用"this.属性"或"this.方法"的方式,调用正在创建的对象属性和方法。但是,通常情况下,我们都选择省略“this.”。特殊情况下,如果构造器的形参和类的属性同名,我们必须显式的使用"this.变量"的方式,表明此变量是属性,而非形参。
7.5this 调用构造器 .我们可以在类的构造器中,显式的使用"this(形参列表)"的方式,调用本类中重载的其他的构造器。
例子:
public class PersonTest{
public static void main(String[] args){
Person p1 = new Person();
p1.setAge(1);
System.out.println(p1.getAge());
p1.eat();
System.out.println();
Person p2 = new Person("Tom",20);
System.out.println(p2.getAge());
}
}
class Person{
//属性
private String name;
private int age;
//构造器
public Person(){
this.eat();
String info = "Person初始化时,需考虑构造器";
System.out.println(info);
}
public Person(String name){
this();
this.name = name;
}
public Person(int age){
this();
this.age = age;
}
public Person(String name,int age){
this(age);//this调用构造器
this.name = name;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name; //this调用属性
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return this.age;
}
public void eat(){
System.out.println("人吃饭");
this.study();
}
public void study(){
System.out.println("人学习");
}
}
08关键字:package、import
package 关键字的使用
1.为了更好的实现项目中类的管理,提供包的概念
2.使用 package 声明类或接口所属的包,声明在源文件的首行
3.包,属于标识符,遵循标识符的命名规则、规范"见名知意"
4.每“.”一次,就代表一层文件目录。
import关键字的使用
import:导入
1.在源文件中显式的使用import结构导入指定包下的类、接口
2.声明在包的声明和类的声明之间
3.如果需要导入多个结构,则并列写出即可
4.可以使用"xxx.*"的方式,表示可以导入xxx包下的所有结构。
5.如果导入的类或接口是java.lang包下的,或者是当前包下的,则可以省略此import语句。
6.如果在代码中使用不同包下的同名的类。那么就需要使用类的全类名的方式指明调用的是哪个类。
7.如果已经导入java.a包下的类。那么如果需要使用a包的子包下的类的话,仍然需要导入。
8.import static组合的使用:调用指定类或接口下的静态的属性或方法.