JavaSE——类与对象、成员变量、封装
今日内容
- 面向对象思想
- 类与对象的使用
- 类与对象的内存图
- 成员变量和局部变量区别
- 封装
1.基础回顾
1.判断语句
有三种格式:
1.第一种格式
//判断条件有两种值:true false
//true 执行大括号内容 false 不执行大括号内容,跳过大括号继续向下执行其他代码
if(判断条件){
}
问题:if后面的大括号是否可以省略?
可以,但是只控制一行代码。
2.第二种格式
两种条件:要么满足条件,要么不满足条件。
//判断条件有两种值:true false
if(判断条件){
//true 执行第一个大括号内容
}else{
//判断条件为false执行第二个大括号内容
}
3.第三种格式
多个条件
if(判断条件1){
}else if(判断条件2){
}else if(判断条件3){
}
.....
else{
//上面都不满足条件执行else中的代码
}
代码演示:
import java.util.Scanner;
/*
多个条件
if(判断条件1){
}else if(判断条件2){
}else if(判断条件3){
}
.....
else{
//上面都不满足条件执行else中的代码
}
*/
public class IfDemo01 {
public static void main(String[] args) {
//需求:根据输入的天数输出对应的星期
//1.创建键盘录入的对象 导包 alt+enter
//生成等号左边的类型和变量:1)在代码new Scanner(System.in) 这里按alt+enter
// 2)new Scanner(System.in).var
Scanner sc = new Scanner(System.in);
System.out.println("请输入天数:");
//2.获取键盘录入的天数
int day = sc.nextInt();
//3.使用判断结构根据输入的天数判断是星期几,然后输出对应的星期
if(day == 1){
System.out.println("星期一");
}else if(day == 2){
System.out.println("星期二");
}else if(day == 3){
System.out.println("星期三");
}else{
System.out.println("您输入的有误");
}
}
}
小结:
- if 判断结构由三种,如果是多个条件建议使用:
if(判断条件1){
}else if(判断条件2){
}else if(判断条件3){
}
.....
else{
//上面都不满足条件执行else中的代码
}
2.生成等号左边的类型和变量:
Scanner sc = new Scanner(System.in);
1)在代码new Scanner(System.in) 这里按alt+enter
2)new Scanner(System.in).var
2.选择结构(多分支结构)
switch(表达式){
case 常量:
语句;
break;
case 常量:
语句;
break;
......
default:
默认语句;
break;
}
问题:
1.表达式取值范围:byte short int char jdk5后增加枚举 jdk7后增加String
2.break作用:停止整个switch语句,建议最好书写,如果不书写会发生case穿透
3. for 循环结构
格式:
for(循环初始化值;循环条件;修改循环条件){
循环体
}
代码演示:
/*
for(循环初始化值;循环条件;修改循环条件){
循环体
}
需求:求1-5和值
*/
public class ForDemo02 {
public static void main(String[] args) {
//1.定义变量保存和值
int sum = 0;
//2.使用for循环提供1-5之间的每个数字 5.fori快捷键
for (int i = 1; i <= 5; i++) {
//3.在for循环体内部对取出的每个数字和sum相加
sum = sum + i;
}
//4.在for循环外部输出和值
System.out.println("sum = " + sum);
}
}
小结:for循环格式:
for(循环初始化值;循环条件;修改循环条件){
循环体
}
4. while 循环
//1.循环初始化值
while(循环条件){
循环体
修改循环条件
}
代码演示:
/*
//1.循环初始化值
while(循环条件){
循环体
修改循环条件
}
*/
public class WhileDemo03 {
public static void main(String[] args) {
// 需求:求1-5和值
//1.定义变量保存和值
int sum = 0;
//2.使用while循环提供1-5之间数字
//循环初始化值
int i = 1;
while(i<=5){//i<=5循环条件
//循环体
sum = sum + i;
//修改变量i的值
i++;//++i 或者i=i+1 i+=1
}
System.out.println("sum = " + sum);
}
}
小结:
1.格式
//1.循环初始化值
while(循环条件){
循环体
修改循环条件
}
5.数组
1.数组可以存储多个类型一致的数据
2.数组长度固定不能改变
3.数组索引0开始,最大索引:数组长度-1
4.定义格式:
1)动态初始化
数据类型[] 数组名 = new 数据类型[数组长度];
int[] arr = new int[3];
2)静态初始化
数据类型[] 数组名 =new 数据类型[]{数据1,数据2,....};
简化版本:
数据类型[] 数组名 ={数据1,数据2,....};
代码演示:
public class ArrayDemo01 {
public static void main(String[] args) {
//动态初始化:数据类型[] 数组名 = new 数据类型[数组长度];
int[] arr = new int[3];
//获取数组中的数据:数组名[索引]
//arr[1] :arr表示数组名 1表示索引
// System.out.println(arr[1]);//默认值是0
//修改值
//修改数组中的数据:数组名[索引] = 数据;
arr[1] = 10;
// System.out.println(arr[1]);//10
/*
静态初始化:
数据类型[] 数组名 =new 数据类型[]{数据1,数据2,....};
简化版本:
数据类型[] 数组名 ={数据1,数据2,....};
*/
//静态初始化数组
int[] arr2 = {10,20,30};
// System.out.println(arr2[1]);
//使用循环遍历数组 快捷键:数组名.fori
for (int i = 0; i < arr2.length; i++) {
System.out.println(arr2[i]);
}
}
}
小结:
- soutv 快捷键:输出离输出语句最近的变量
6.方法
作用:提高代码复用性的。
格式:
方法修饰符 方法返回值类型 方法名(参数列表){
方法体
1
}
注意:
1.如果该方法没有返回值直接在方法返回值类型处书写void
2.如果方法有返回值,使用return返回即可,对于方法返回值类型处书写什么具体的数据类型看return后面返回的数 据
3.方法必须被调用才能执行
代码演示:
/*
方法修饰符 方法返回值类型 方法名(参数列表){
方法体
}
注意:
1.如果该方法没有返回值直接在方法返回值类型处书写void
2.如果方法有返回值,使用return返回即可,对于方法返回值类型处书写什么具体的数据类型看return后面返回的数 据
3.方法必须被调用才能执行
*/
public class FunctionDemo04 {
public static void main(String[] args) {
//需求:使用方法对求1-5之间和值并返回
//3.方法必须被调用才能执行
//3.1调用有返回值的方法但是没有接收返回结果
// getSum();
//3.2调用有返回值的方法并且接收结果
/*int sum = getSum();
System.out.println("sum = " + sum);*/
//3.3调用有返回值的方法直接输出结果
System.out.println("和值是:"+getSum());
}
//定义方法
//返回值这里书写int是因为return后面返回的sum属于int类型
public static int getSum(){
//1.定义变量保存和值
int sum = 0;
//2.使用for循环提供1-5之间的每个数字 5.fori快捷键
for (int i = 1; i <= 5; i++) {
//3.在for循环体内部对取出的每个数字和sum相加
sum = sum + i;
}
//使用return返回和值
return sum;
}
}
小结:
1.方法定义格式:
方法修饰符 方法返回值类型 方法名(参数列表){
方法体
}
注意:
1.如果该方法没有返回值直接在方法返回值类型处书写void
2.如果方法有返回值,使用return返回即可,对于方法返回值类型处书写什么具体的数据类型看return后面返回的数 据
3.方法必须被调用才能执行
2.有参方法:
public class FunctionDemo05 {
public static void main(String[] args) {
//有参方法调用方法 在调用语句位置快速生成方法快捷键:alt+enter
method(10,1.2);
}
//方法形参位置能够书写什么数据类型看调用语句传递的实参类型
public static void method(int i, double v) {
}
}
7.内存分配
jvm分配5块内存区域:
1.栈内存:所有与方法运行都在栈内存运行,在栈内存顶部运行
2.堆内存:只要使用new关键字开辟的空间都是在堆内存中
3.方法区:存放.class文件
4.寄存器:给cpu使用
5.本地方法区:给底层的一些内容使用native
2.面向对象思想
1.引入
/*
数组工具类
*/
public class ArrayTools {
//这个方法是对数组求和值的
public static int getArraySum(int[] arr) {
//3.定义变量保存和值
int sum = 0;
//4.遍历数组取出每个数据和sum求和
for (int i = 0; i < arr.length; i++) {
sum = sum + arr[i];
}
//返回和值sum
return sum;
}
}
/*
问题:我们在不同类中对int类型数组求和值,发现每个类的求和方法代码是一样的
代码出现重复,我们是否可以只定义一遍方法,然后在不同类中使用呢?
可以,我们可以将对数组求和的方法定义在一个类中,然后其他类直接使用即可
*/
public class Demo02 {
public static void main(String[] args) {
//定义数组
int[] arr = {100,200,300,400,500};
//创建数组工具类ArrayTools类的对象
ArrayTools t = new ArrayTools();
//调用方法对数组求和值
int sum = t.getArraySum(arr);
System.out.println("sum = " + sum);
}
}
/*
需求:对数组求和值
*/
public class Demo01 {
public static void main(String[] args) {
//需求:对数组求和值
//1.定义数组
int[] arr = {10,20,30};
/*
我们发现在Demo01类中调用ArrayTools类中的求和方法,
不能通过方法名直接调用,因为通过方法名直接调用的方式
是位于同一个类中,我们需要借助于ArrayTools类的对象
这里创建ArrayTools类的对象格式:
Scanner sc = new Scanner(System.in);
ArrayTools tool = new ArrayTools();
说明:
1.new ArrayTools() 创建ArrayTools对象
2.tool表示对象名,属于标识符,随意
3.ArrayTools tool :ArrayTools类表示tool对象名所属的类
*/
ArrayTools tool = new ArrayTools();
/*
对象创建好之后,如果使用类中的方法,可以按照如下使用:
对象名.方法名(实参);
*/
//2.调用方法
int sum = tool.getArraySum(arr);
System.out.println("sum = " + sum);
}
}
小结:
1.如果使用不同类中的方法必须创建对象
ArrayTools tool = new ArrayTools();
说明:
1.new ArrayTools() 创建ArrayTools对象
2.tool表示对象名,属于标识符,随意
3.ArrayTools tool :ArrayTools类表示tool对象名所属的类
2.使用对象调用方法:
int sum = tool.getArraySum(arr);//对象名.方法名(实参);
3.面向对象好处:减少代码重复性问题。
2.面向对象思想
面向(看)过程思想:看整个过程。
吃饭:
1.去菜市场买菜
2.回家摘菜 洗菜 切菜 炒菜
3.焖饭 吃饭
4.洗刷
语言:c语言
面向对象思想:
吃饭:
1.去饭店吃
2.进入饭店找服务员,点菜
3.点完菜,手机摇一摇,服务员将菜单给大厨
4.大厨做好菜将菜给我们吃
5.结账
面向对象从劳动力变为指挥者。
语言:java c++
小结:以后我们遇到问题先不要着急自己去完成,而是先看有没有写好的,我们可以直接
使用即可。
3.类和对象(理解)
类:属于抽象的,表示一类事物。例如人类 动物类
对象:就是真正存在的,具体的。T哥 T哥的家猫
类和对象关系:先有类,后有对象。
举例:人类
public class Person{
//属性或者特点
姓名
年龄
身高
体重
。。。
行为:使用方法表示
吃饭(){}
睡觉(){}
学习(){}
}
定义类代码演示:
/*
描述人类
*/
public class Person {
// 属性或者特点:使用变量描述:定义格式:数据类型 变量名;
// 姓名
String name;
// 年龄
int age;
//
// 行为:使用方法表示
// 吃饭(){}
public void eat(){
System.out.println("eat....");
}
// 学习(){}
public void study(){
System.out.println("学习java");
}
}
使用对象操作类中的属性和方法:
public class PersonTest01 {
public static void main(String[] args) {
/*
1.创建Person类的对象
创建对象格式:类名 对象名 = new 类名();
1)new Person(); 创建Person类的对象
2)p:表示对象名
3)前面的Person表示p所属的类
*/
Person p = new Person();
/*
2.使用对象操作类中的属性:
1)对象名.属性名:获取类中的属性值
2)对象名.属性名 = 数据;给类中的属性赋值
*/
//获取name属性值
// String n = p.name;
System.out.println(p.name);//null
//int a = p.age
System.out.println(p.age);//0
//给name和age赋值
// 2)对象名.属性名 = 数据;给类中的属性赋值
p.name = "T哥";
p.age = 18;
System.out.println(p.name);//T哥
//int a = p.age
System.out.println(p.age);//18
/*
3.使用对象操作行为或者方法
格式:对象名.方法名(实参);
说明:
1)如果没有实参可以不传递
2)如果被调用的方法有返回值需要使用变量接收
*/
p.eat();
p.study();
}
}
小结:
1.只要使用不同类中的属性或者方法必须使用类的对象
2.创建对象格式:
创建对象格式:类名 对象名 = new 类名();
1)new Person(); 创建Person类的对象
2)p:表示对象名
3)前面的Person表示p所属的类
3.对象操作类的属性:
使用对象操作类中的属性:
1)对象名.属性名:获取类中的属性值
2)对象名.属性名 = 数据;给类中的属性赋值
4.使用对象操作方法
使用对象操作行为或者方法
格式:对象名.方法名(实参);
说明:
1)如果没有实参可以不传递
2)如果被调用的方法有返回值需要使用变量接收
4.成员变量的默认值
成员变量(属性):位于方法外部,类中。如果成员变量不赋值,那么是有默认值的。
数据类型 | 默认值 | |
---|---|---|
基本类型 | 整数(byte,short,int,long) | 0 |
浮点数(float,double) | 0.0 | |
字符(char) | ‘\u0000’(unicode码表中)ascii | |
布尔(boolean) | false | |
引用类型 | 数组,类,接口 | null |
5.对象内存图体现
1.一个对象
代码实现:
public class Student {
//定义成员变量(属性)
String name;
int age;
//定义方法/行为
public void study(){
System.out.println("学习java");
}
}
public class StudentTest01 {
public static void main(String[] args) {
//创建学生对象
Student s = new Student();
System.out.println(s);
//使用对象获取值并输出
System.out.println(s.name);
System.out.println(s.age);
//使用对象给成员变量赋值
s.name = "T哥";
s.age = 19;
//使用对象获取值并输出
System.out.println(s.name);
System.out.println(s.age);
//使用对象调用方法
s.study();
}
}
2.两个对象内存图
public class StudentTest02 {
public static void main(String[] args) {
//1.创建学生对象
Student s1 = new Student();
//给成员变量赋值
s1.name = "柳岩";
s1.age = 20;
//获取成员变量并输出结果
System.out.println(s1.name);
System.out.println(s1.age);
s1.study();
//2.创建学生对象
Student s2 = new Student();
//给成员变量赋值
s2.name = "杨幂";
s2.age = 21;
//获取成员变量并输出结果
System.out.println(s2.name);
System.out.println(s2.age);
s2.study();
}
}
小结:使用new创建某个类多个对象,会在堆内存中开辟多个对象空间。
3.多个对象变量空间保存同一个对象地址值
public class StudentTest03 {
public static void main(String[] args) {
//创建学生对象
Student s1 = new Student();
//使用对象给类中成员变量赋值
s1.name = "柳岩";
s1.age = 19;
//定义对象变量
//将s1中的地址值赋值给s2
Student s2 = s1;
System.out.println(s1.name);
System.out.println(s1.age);
System.out.println(s2.name);
System.out.println(s2.age);
}
}
小结:如果一个对象将空间的地址值赋值给另一个对象引用变量,那么这两个对象引用变量
指向堆内存同一个对象空间。
6.成员变量和局部变量(掌握)
成员变量:位于类中方法外部的变量
补充:类中方法外部的位置我们也称为类的成员位置。位于类的成员位置的变量是成员变量。位于成员位置的方法称为成员方法。
局部变量:位于局部位置,方法内部。
代码演示:
/*
成员变量:位于类中方法外部的变量
补充:类中方法外部的位置我们也称为类的成员位置。位于类的成员位置的变量是成员变量。位于成员位置的方法称为成员方法。
局部变量:位于局部位置,方法内部。
注意事项:
1.成员变量和局部变量同名了,根据就近原则优先使用局部变量
2.成员变量和局部变量区别:
1)成员变量随着对象创建在堆内存中,是有默认值
2) 由于局部变量定义在方法体内部,随着方法在栈内存
开辟空间开存在,不赋值是没有默认值,不能使用
3)生命周期:
成员变量:对随着对象创建出现在堆内存中
局部变量:随着方法出现在栈内存中
*/
public class Person {
//成员位置
//成员变量
String name;
int age = 10;
//定义成员变量
int x = 30;
//成员方法
public void say(){
//局部位置,定义局部变量
int x = 20;
int y;
System.out.println("x = " + x);//20
System.out.println("age = " + age);//10
System.out.println("name = " + name);//null
// System.out.println("y = " + y);
}
}
public class Test01 {
public static void main(String[] args) {
//创建Person对象
Person p = new Person();
//使用对象p调用成员方法
p.say();
}
}
7.封装(必须掌握)
面向对象语言三大特征:封装 继承 多态
代码演示:
/*
1.我们发现对于成员变量age,在测试类中可以直接赋值为负数,
显然出现了安全问题,我们如何解决呢?
使用封装解决,就是将成员变量给封装(包装)起来。
在java中如果一个成员变量想被封装,那么使用关键字private。
2.private属于成员修饰符,用来修饰成员变量 成员方法 构造方法。
表示私有的,被private修饰的成员内容只能在本类中使用
3.
修饰成员变量格式:private 数据类型 变量名;
修饰成员方法:
private 方法返回值类型 方法名(参数列表){}
4.被private修饰的成员变量不能在其他类直接使用对象访问,
可以间接访问,使用方法访问
*/
public class Person {
//成员位置
//成员变量
//private 数据类型 变量名;
private int age;
//定义成员方法给age赋值
public void setAge(int a){//int a=18
//使用判断语句判断a是否合法,合法给成员变量赋值,
// 不合法不赋值
if (a > 0 && a < 120) {
//合法
age = a;
}else{
//非法
System.out.println("年龄非法");
}
}
//在定义一个方法用来让其他类获取age值
public int getAge(){
//返回给调用者age的值
return age;
}
//成员方法
public void say(){
System.out.println("我叫T哥,我今年"+age);
}
}
public class Test01 {
public static void main(String[] args) {
//创建Person对象
Person p = new Person();
//使用对象p给成员变量age赋值
// p.age = -18;
// p.age = 18;
//调用方法给age赋值
p.setAge(18);
//使用对象p调用方法
// p.say();
//查看age的值
int age = p.getAge();
System.out.println(age);
}
}
小结:
1.封装作用:安全。
2.封装使用关键字private,属于成员修饰符,可以修饰成员变量 方法 构造方法
3.使用private修饰的内容只能在本类使用
4.如果一个成员变量被private修饰了,我们需要对外提供setXxx() 个getXxx()方法
setAge()赋值
getAge()获取值
5.封装练习
public class Student {
//定义成员变量
private String name;
private int age;
private String address;
//使用快捷键快速生成成员变量对应的set get方法:1) alt+insert 2)右键--》generate
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
小结:
使用快捷键快速生成成员变量对应的set get方法:1) alt+insert 2)右键–》generate
推荐阅读
-
C#类中属性与成员变量的使用小结
-
Java之反射第十八天( --反射----类的加载--获取对象属性( 成员变量和方法)-- 构造方法 )
-
Java面向对象之成员隐藏与属性封装操作示例
-
Java面向对象之成员隐藏与属性封装操作示例
-
Python面向对象程序设计中类的定义、实例化、封装及私有变量/方法详解
-
PHP封装mysqli基于面向对象的mysql数据库操作类与用法示例
-
Python面向对象程序设计中类的定义、实例化、封装及私有变量/方法详解
-
Python面向对象程序设计类变量与成员变量、类方法与成员方法用法分析
-
Python面向对象程序设计类的封装与继承用法示例
-
net学习之类与对象、new关键字、构造函数、常量和只读变量、枚举、结构、垃圾回收、静态成员、静态类等