第四章:面向对象(上)
4.1面向对象
面向对象:关注的是具有功能的对象
面向对象的三条主线:
1.类和类的成员
- 属性(field)
- 方法(method)
- 构造器(constructor)
- 语句块
- 内部类
2.三大特征
- 封装(encapsulation)
- 继承(inheritance)
- 多态(polymorphism)
3.其他关键字
this,super,package,import,extends,interface,implements,static,final,abstract
4.2类
**类:**某种事物的描述(对某种事物的统一抽象定义)
**对象:**类的实体,也称为实例
- 类中用属性(成员变量)描述事物特征
- 类中用方法(成员方法)描述事物行为,动作
- 成员可以互访,因为成员都是隶属于同一个类
创建对象的过程称为:实例化 new 类名();
成员变量:
- 成员变量定义在类中,在整个类中都可以被访问
- 成员变量分为类成员变量和实例成员变量,实例变量存在于对象所在的堆内存中
- 成员变量有默认初始化值
- 成员变量的权限修饰符可以根据需要任选一个
局部变量:
- 局部变量只定义在局部范围内,比如方法内,代码块内
- 局部变量存在于栈内存中
- 作用的范围结束,变量空间会自动释放
- 局部变量没有默认初始化值,每次必须显示初始化
- 局部变量声明时不指定权限修饰符
匿名对象:
创建对象后并没有引用指向,适用于对象的一次性使用的情况
类模板:
-
包含了 属性的定义信息
-
包含了 所有 方法的代码
package:
package com.atguigu.javase.javabean;
/**
* package语句用于打包, 作用是把生成的.class放入指定的包目录结构中.
* package 包名.子包名.子子包名.子子子包名; // 包名全部小写
* 必须放在源文件中最上面, 作用于当前源文件中的所有类
*
* package 机构类型.机构名称.项目名称.模块名称;
* package com.atguigu.javase.javabean;
*
* package带来的麻烦 :
* 1) 编译 javac -d 目标目录 源文件名
* 2) 如果在其他包中再使用本类时, 就必须使用类的全限定名称(fully qualified name)
* 包名.子包名.子子包名.子子子包名.类名.
*
* import 语句必须位于package 下面
* 作用是把其他包中的类导入, 告诉编译器要使用的其他包的类该如何定位.
* 一旦导入了类, 就可以省略全限定名称的写法. 只使用简单类名即可.
JavaBean : 可重用组件
- 类是公共的 : 便于所有范围使用
- 有公共无参构造器 : 便于创建对象
- 有属性, 有get/set : 每个对象都可以携带批量的数据.
类创建对象的方式:
- 在永久区中查找要创建的对象所隶属的类模板数据是否已加载
- 如果没有加载则由类加载器(ClassLoader)来加载类
- 如果类模板已经加载过了,则不加载,保证类模板只有一份
- 依据类模板中所有属性的信息(数据类型 ,属性名)在GC区中开辟相应的空间
- JVM负责将此空间数据全部清零,结果是所有属性都自动拥有缺省值0
- 执行属性的显示赋值
- 执行构造方法
- 返回对象的首地址
4.3封装
private:私有,用它修饰的成员,只能在本类中使用
set方法:用于间接给属性赋值,有参无返回
get方法:用于间接获取属性值,无参有返回
**封装:**成员私有化,保护对象中的属性数据的合法合理性
- 隐藏一个类中不需要对外提供的实现细节
- 只对外提供简单的接口,便于外界调用,从而提高系统的可扩展性、可维护性
- 使用者只能通过事先定制好的方法来访问数据,可以方便地加入控制逻辑,限制对属性的不合理操作
- 便于修改,增强代码的可维护性
**构造器(constructor):**在创建对象时进行初始化工作
特殊性;
- 方法名必须和类名字一致,唯一允许首字母大写的方法
- 不声明返回值类型
- 不能被一些关键字修饰:static,final,abstract,synchronized…
- 构造器不能像普通方法一样随意调用,只能在创建对象时调用仅有的一次
- 如果类中没有写构造器,编译器会自动添加一个缺省构造器
构造器注意点 :
-
Java语言中,每个类都至少有一个构造器,默认构造器的修饰符与所属类的修饰符一致
-
一旦显式定义了构造器,则系统不再提供默认构造器,一个类可以创建多个重载的构造器
-
父类的构造器不可被子类继承
-
使用this()必须放在构造器的首行!
-
使用this调用本类中其他的构造器,保证至少有一个构造器是不用this的,防止无限递归。
4.4方法
方法
/*
方法(method) : 也称为函数(function), 是java程序中的一个独立的功能单位. 用于完成某个功能.
方法的声明 :
修饰符 返回值类型 方法名(数据类型1 形式参数1, 数据类型2 形式参数2, ....) {
语句块;
return 返回值;
}
返回值类型 : 方法功能的成果数据类型.
方法名 : 标识符, 用于定位
形式参数 : 方法的功能的完成需要一些数据的支持, 没有数据不行, 但是数据是多少并不影响功能.
返回值 : 方法的最终的成果数据值. 最后要返回给调用者(使用者)
方法 = 方法签名(方法的使用说明书API) + 方法体(参数后面的一对{}及其中的内容)(由语句构成)
真正执行的是方法体, 方法签名不执行.
方法必须要隶属于类, 且不可以嵌套, 类中的方法只能并列存在.
方法必须要被调用(invoke)才执行.
方法调用语句:
方法名(实际参数列表); // 实参列表必须要符合形参列表要求
方法的返回值 : 返回值的接收只有一次机会, 就是在调用的同时, 如果错过了就错过了
变量 = 方法调用本身.
方法写法 : 1) 有参有返回, 2) 无参无返回, 3) 有参无返回, 4) 无参有返回
int add(int a, int b)
void add()
void add(int a, int b)
int add()
如果方法没有返回值, 在方法中的最后的return可以省略, 写上也可以, 但是后面不能带数据.
如果方法没有参数, 方法声明时的一对()不能省略, 调用时的一对()也绝对不能省略.
如果方法有返回值声明, 则在方法中必须要有return 值
注 意:
没有具体返回值的情况,返回值类型用关键字void表示,那么该函数中的return语句如果在最后一行可以省略不写。
定义方法时,方法的结果应该返回给调用者,交由调用者处理。
方法中只能调用方法,不可以在方法内部定义方法。
方法的返回值只有一次机会接收, 就是在调用时
如果在方法中又调用了方法本身, 称为递归调用
public class MethodTest {
// 方法 : 求2个整数的和
// 修饰符 返回值类型 方法名(数据类型1 形式参数1, 数据类型2 形式参数2, ....)
public static int add(int a, int b) {
System.out.println("add(int a, int b)...");
int c = a + b;
return c; // 返回的是c变量中的值的副本
}
// 最简单方法, 无参无返回
public static void test() {
System.out.println("test()1...");
System.out.println("test()2...");
System.out.println("test()3...");
//return;
}
public static void main(String[] args) {
System.out.println("main begin");
// 下面的写法适用于返回值的多次使用.
int x = add(10, 20); // 10, 20称为实参列表, 返回值必须在同一行接收!!!
//System.out.println(c); // 不可以跨方法访问另外的方法中的局部变量!!!
System.out.println(x);
// 下面的写法适用于返回值的临时使用
// 下面是2个方法的嵌套调用, add先执行, println后执行
System.out.println(add(50, 90)); // 打印的是方法调用, 最终打印的是返回值.
//int y = test(); // ()是方法调用的标志. 方法如果没有返回值, 千万不要接收.
//System.out.println(test()); // 方法如果没有返回值, 绝对不能打印它的方法调用!!!
test(); // 纯调用即可
System.out.println("main end");
}
}
// 方法调用 :
// 1. 调用者方法要给被调用方法传递参数(通过赋值的方式)
// 2. 调用者方法作现场保护, 流程交给被调用. 此时调用者方法就挂起, 暂停了
// 3. 被调用方法开始一行一行的执行, 直接执行完毕返回
// 4. 返回到调用者方法, 作现场恢复, 继续执行后面的代码.
4.5重载
**重载(overLoad) 😗*也称为过载, 因为太多了, 方法名相同,但是参数不同.
第四章:面向对象(上)
4.1面向对象
面向对象:关注的是具有功能的对象
面向对象的三条主线:
1.类和类的成员
- 属性(field)
- 方法(method)
- 构造器(constructor)
- 语句块
- 内部类
2.三大特征
- 封装(encapsulation)
- 继承(inheritance)
- 多态(polymorphism)
3.其他关键字
this,super,package,import,extends,interface,implements,static,final,abstract
4.2类
**类:**某种事物的描述(对某种事物的统一抽象定义)
**对象:**类的实体,也称为实例
- 类中用属性(成员变量)描述事物特征
- 类中用方法(成员方法)描述事物行为,动作
- 成员可以互访,因为成员都是隶属于同一个类
创建对象的过程称为:实例化 new 类名();
成员变量:
- 成员变量定义在类中,在整个类中都可以被访问
- 成员变量分为类成员变量和实例成员变量,实例变量存在于对象所在的堆内存中
- 成员变量有默认初始化值
- 成员变量的权限修饰符可以根据需要任选一个
局部变量:
- 局部变量只定义在局部范围内,比如方法内,代码块内
- 局部变量存在于栈内存中
- 作用的范围结束,变量空间会自动释放
- 局部变量没有默认初始化值,每次必须显示初始化
- 局部变量声明时不指定权限修饰符
匿名对象:
创建对象后并没有引用指向,适用于对象的一次性使用的情况
类模板:
-
包含了 属性的定义信息
-
包含了 所有 方法的代码
package:
package com.atguigu.javase.javabean;
/**
* package语句用于打包, 作用是把生成的.class放入指定的包目录结构中.
* package 包名.子包名.子子包名.子子子包名; // 包名全部小写
* 必须放在源文件中最上面, 作用于当前源文件中的所有类
*
* package 机构类型.机构名称.项目名称.模块名称;
* package com.atguigu.javase.javabean;
*
* package带来的麻烦 :
* 1) 编译 javac -d 目标目录 源文件名
* 2) 如果在其他包中再使用本类时, 就必须使用类的全限定名称(fully qualified name)
* 包名.子包名.子子包名.子子子包名.类名.
*
* import 语句必须位于package 下面
* 作用是把其他包中的类导入, 告诉编译器要使用的其他包的类该如何定位.
* 一旦导入了类, 就可以省略全限定名称的写法. 只使用简单类名即可.
JavaBean : 可重用组件
- 类是公共的 : 便于所有范围使用
- 有公共无参构造器 : 便于创建对象
- 有属性, 有get/set : 每个对象都可以携带批量的数据.
类创建对象的方式:
- 在永久区中查找要创建的对象所隶属的类模板数据是否已加载
- 如果没有加载则由类加载器(ClassLoader)来加载类
- 如果类模板已经加载过了,则不加载,保证类模板只有一份
- 依据类模板中所有属性的信息(数据类型 ,属性名)在GC区中开辟相应的空间
- JVM负责将此空间数据全部清零,结果是所有属性都自动拥有缺省值0
- 执行属性的显示赋值
- 执行构造方法
- 返回对象的首地址
4.3封装
private:私有,用它修饰的成员,只能在本类中使用
set方法:用于间接给属性赋值,有参无返回
get方法:用于间接获取属性值,无参有返回
**封装:**成员私有化,保护对象中的属性数据的合法合理性
- 隐藏一个类中不需要对外提供的实现细节
- 只对外提供简单的接口,便于外界调用,从而提高系统的可扩展性、可维护性
- 使用者只能通过事先定制好的方法来访问数据,可以方便地加入控制逻辑,限制对属性的不合理操作
- 便于修改,增强代码的可维护性
**构造器(constructor):**在创建对象时进行初始化工作
特殊性;
- 方法名必须和类名字一致,唯一允许首字母大写的方法
- 不声明返回值类型
- 不能被一些关键字修饰:static,final,abstract,synchronized…
- 构造器不能像普通方法一样随意调用,只能在创建对象时调用仅有的一次
- 如果类中没有写构造器,编译器会自动添加一个缺省构造器
构造器注意点 :
-
Java语言中,每个类都至少有一个构造器,默认构造器的修饰符与所属类的修饰符一致
-
一旦显式定义了构造器,则系统不再提供默认构造器,一个类可以创建多个重载的构造器
-
父类的构造器不可被子类继承
-
使用this()必须放在构造器的首行!
-
使用this调用本类中其他的构造器,保证至少有一个构造器是不用this的,防止无限递归。
4.4方法
方法
/*
方法(method) : 也称为函数(function), 是java程序中的一个独立的功能单位. 用于完成某个功能.
方法的声明 :
修饰符 返回值类型 方法名(数据类型1 形式参数1, 数据类型2 形式参数2, ....) {
语句块;
return 返回值;
}
返回值类型 : 方法功能的成果数据类型.
方法名 : 标识符, 用于定位
形式参数 : 方法的功能的完成需要一些数据的支持, 没有数据不行, 但是数据是多少并不影响功能.
返回值 : 方法的最终的成果数据值. 最后要返回给调用者(使用者)
方法 = 方法签名(方法的使用说明书API) + 方法体(参数后面的一对{}及其中的内容)(由语句构成)
真正执行的是方法体, 方法签名不执行.
方法必须要隶属于类, 且不可以嵌套, 类中的方法只能并列存在.
方法必须要被调用(invoke)才执行.
方法调用语句:
方法名(实际参数列表); // 实参列表必须要符合形参列表要求
方法的返回值 : 返回值的接收只有一次机会, 就是在调用的同时, 如果错过了就错过了
变量 = 方法调用本身.
方法写法 : 1) 有参有返回, 2) 无参无返回, 3) 有参无返回, 4) 无参有返回
int add(int a, int b)
void add()
void add(int a, int b)
int add()
如果方法没有返回值, 在方法中的最后的return可以省略, 写上也可以, 但是后面不能带数据.
如果方法没有参数, 方法声明时的一对()不能省略, 调用时的一对()也绝对不能省略.
如果方法有返回值声明, 则在方法中必须要有return 值
注 意:
没有具体返回值的情况,返回值类型用关键字void表示,那么该函数中的return语句如果在最后一行可以省略不写。
定义方法时,方法的结果应该返回给调用者,交由调用者处理。
方法中只能调用方法,不可以在方法内部定义方法。
方法的返回值只有一次机会接收, 就是在调用时
如果在方法中又调用了方法本身, 称为递归调用
public class MethodTest {
// 方法 : 求2个整数的和
// 修饰符 返回值类型 方法名(数据类型1 形式参数1, 数据类型2 形式参数2, ....)
public static int add(int a, int b) {
System.out.println("add(int a, int b)...");
int c = a + b;
return c; // 返回的是c变量中的值的副本
}
// 最简单方法, 无参无返回
public static void test() {
System.out.println("test()1...");
System.out.println("test()2...");
System.out.println("test()3...");
//return;
}
public static void main(String[] args) {
System.out.println("main begin");
// 下面的写法适用于返回值的多次使用.
int x = add(10, 20); // 10, 20称为实参列表, 返回值必须在同一行接收!!!
//System.out.println(c); // 不可以跨方法访问另外的方法中的局部变量!!!
System.out.println(x);
// 下面的写法适用于返回值的临时使用
// 下面是2个方法的嵌套调用, add先执行, println后执行
System.out.println(add(50, 90)); // 打印的是方法调用, 最终打印的是返回值.
//int y = test(); // ()是方法调用的标志. 方法如果没有返回值, 千万不要接收.
//System.out.println(test()); // 方法如果没有返回值, 绝对不能打印它的方法调用!!!
test(); // 纯调用即可
System.out.println("main end");
}
}
// 方法调用 :
// 1. 调用者方法要给被调用方法传递参数(通过赋值的方式)
// 2. 调用者方法作现场保护, 流程交给被调用. 此时调用者方法就挂起, 暂停了
// 3. 被调用方法开始一行一行的执行, 直接执行完毕返回
// 4. 返回到调用者方法, 作现场恢复, 继续执行后面的代码.
4.5重载
**重载(overLoad) 😗*也称为过载, 因为太多了, 方法名相同,但是参数不同.
参数不同体现为 : 参数类型不同, 个数不同, 顺序不同.
与返回值类型无关,只看参数列表
重载的多个方法定位 : 通过实参来决定的
重载的多个方法的匹配度不一样, 优先精准匹配, 再兼容性匹配.
当实参和形参兼容匹配时, 如果有多个方法匹配度都一样, 会编译出错!!!
同名的目的就是为了表明这些个方法具有相同或类似的功能
调用者简单的调用同名方法, 不需要记多个名称. 只需要 记一个就可以了. 调用时传入不同实参, 感觉像调用同一个方法.
设计者复杂了.
可变个数形参的方法:
- 可变个数形参的格式:(数据类型… 变量名)
- 当调用可变个数形参的方法时,传入的参数个数可以是:0个,1个,2个…
- 可变个数形参的方法与本类中方法名相同,形参个数不同的方法之间构成重载
- 方法名相同,形参类型也相同的数组之间不构成重载
- 可变个数形参在方法的形参中必须声明在末尾
- 可变个数形参在方法的形参中,最多声明一个可变形参方法名相同
参数不同体现为 : 参数类型不同, 个数不同, 顺序不同.
与返回值类型无关,只看参数列表
重载的多个方法定位 : 通过实参来决定的
重载的多个方法的匹配度不一样, 优先精准匹配, 再兼容性匹配.
当实参和形参兼容匹配时, 如果有多个方法匹配度都一样, 会编译出错!!!
同名的目的就是为了表明这些个方法具有相同或类似的功能
调用者简单的调用同名方法, 不需要记多个名称. 只需要 记一个就可以了. 调用时传入不同实参, 感觉像调用同一个方法.
设计者复杂了.
可变个数形参的方法:
- 可变个数形参的格式:(数据类型… 变量名)
- 当调用可变个数形参的方法时,传入的参数个数可以是:0个,1个,2个…
- 可变个数形参的方法与本类中方法名相同,形参个数不同的方法之间构成重载
- 方法名相同,形参类型也相同的数组之间不构成重载
- 可变个数形参在方法的形参中必须声明在末尾
- 可变个数形参在方法的形参中,最多声明一个可变形参方法名相同