Java面向对象(上)
类和对象的的使用
package org.atguigu.java;
/*
* 类和对象的使用(面向对象思想落地的实现)
* 1.创建类,设计类的成员
* 2.创建类的对象
* 3.通过“对象.属性”或“对象.方法”调用对象的结构
*/
//测试类
public class PersonTest {
public static void main(String[] args)
{
Person p1 = new Person();
//调用对象的结构属性、方法
p1.name = "Tom";
p1.isMale = true;
System.out.println(p1.name);
//调用方法
p1.eat();
p1.sleep();
p1.talk("chinese");
}
}
class Person
{
String name;
int age;
boolean isMale;
public void eat()
{
System.out.println("人可以吃饭");
}
public void sleep()
{
System.out.println("人可以睡觉");
}
public void talk(String Language)
{
System.out.println("人可以说话,用" + Language);
}
}
内存解析
属性(成员变量) VS 局部变量
1.相同点:
1.1定义变量的格式,数据类型 变量名= 变量值
1.2先声明,后使用
1.3变量都有其对应的作用域
2.不同点
2.1在类中声名的位置不同
属性:直接定义再类的一堆{}内
局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量
2.2关于权限修饰符的不同
属性:可以在声明属性时,指明其权限,使用权限修饰符
常用的权限修饰符:private,public,缺省(系统默认状态),protected -->封装性
局部变量:不能使用权限修饰符
2.3默认初始化值的情况:
属性:类的属性,根据其类型,都有默认初始化值
局部变量:没有初始化值
意味着,我们再调用局部变量之前,一定要赋值
特别地,形参再调用时,我们赋值即可
2.4再内存中加载的位置:
属性:加载到堆空间中(非static)
局部变量:加载到栈空间
重载
要想弄清重载,得知道为啥要有这个东西,存在意义在哪里
像这种
对不同参数类型,不同参数个数,但却希望有相同函数名的情况时时发生,所以也就会存在重载,比如我们print一个int,和print一个String,这肯定是不一样的函数,但都是打印,于是我们希望可以用相同函数名来进行函数定义,重载其实是应运而生
overloading定义
1.定义:
在同一一个类中,允许存在一个以 上的同名方法,只要它们的参数个数或者参数类型不同即可。
"两同不同”:同-个类、相同方法名
参数列表不同:参数个数不同,参数类型不同
2.判断是否时重载
跟方法的权限修饰符、返回值类型、形参变量名、方法体都没有关系!
3.在通过对象调用方法时,如何确定某一 个指定的方法:
方法名--->参数列表
Tips
返回值并不在判断是否重载的标准内,可以这样理解:如果返回值不同也可以重载,函数定义时,参数个数类型都完全相同,函数名也相同,那么调用的时候,返回的是什么连自己也说不清楚,更别说编译器了
可变个数形参的方法
1.jdk 5.0新增的内容
2.具体使用
2.1 可变个数形参的形式: 数据类型 ... 变量名
2.2 当调用可变个数形参的方法时,传入的参数可以是一个,零个,两个。。。。
2.3 可变个数的形参可以重载
2.4 与相同类型的数组作为 参数的函数不能重载
调用时更数组一样
2.5可变个数形参在方法的形参中,必须声明在末尾
2.6可变个数形参在方法的形参中,最多只能声明一个可变形参。
关于变量的赋值:
如里变量是基本数据类型,此时赋值的是变量所保存的数据值。
如果变量是引用数据类型,此时赋值的是变量所保存的数据的地址值。
java中对象变量都是指针
如果是传递参数,基本数据类型传递的是一个具体的值,相当于复制了一份(在栈区)
引用数据类型传递的是一个地址,相当于直接指向了原来的的数据(在堆区)
//错误代码
public class TestArray { public static void main(String[] args) { TestArray demo = new TestArray(); int m = 10; int n = 20; demo.Echg(m,n); System.out.println(m); System.out.println(n); } public void Echg(int a,int b) { int temp = a; a = b; b = temp; } }
结果并没有像我们希望的两个值交换,就是因为时复制了一份来处理
我们应该用引用类型来处理,直接指向首地址
public class TestArray { public static void main(String[] args) { TestArray demo = new TestArray(); demo1 data = new demo1(); data.m =10; data.n =20; demo.Echg(data); System.out.println(data.m); System.out.println(data.n); } public void Echg(demo1 data) { int temp = data.m; data.m =data.n; data.n = temp; } } class demo1 { int m; int n; }
交换成功了
面向对象的特征一:封装与隐藏
一、问题的引入:
当我们创建一个类的对象以后,我们可以通过"对象.属性"的方式,对对象的属性进行赋值。这里,赋值操作要受主属性的数据类型和存储范围的制约。除此之外,没有其他制约条件。但是,在实际问题中,我们往往需要给属性赋值,加入额外的限制条件。这个条件就不能在属性声明时体现,我们只能通过方法进行限制条件的添加。(比如: set同时,我们需要避免用户再使用"对象.属性"的方式对属性进行赋值。则需要将属性声明为私有的(private)-->此时,针对于属性就体现了封装性。
二、封装性的体现:
我们将类的属性xxx私有化(private),同时,提供公共的(public)方法来获取(getxxx)和设置(setxxx)
拓展:封装性的体现:如上不对外暴露的私有的方法③单例模式...
三、封装性的体现,需要权限修饰符来配合。
1.Java规定的4种权限(从小到大排列):private、缺省、protectedI、 public
2.4种权限可以用来修饰类及类的内部结构:属性、方法、构造器、内部类
3.具体的,4种权限都可以用来修饰类的内部结构:属性、方法、构造器、内部类
修饰类的话,只能使用:缺省、public
我们程序设计追求“高内聚,低耦合”。
>高内聚:类的内部数据操作细节自己完成,不允许外部干涉;
>低耦合:仅对外暴露少量的方法用于使用。
一、构造器(构造函数)的作用:
1.创建对象
2.初始化对象的信息
二、说明:
1.如果没有显式的定义类的构造器的话,则系统默认提供一个空参的构造器
2.定义构造器的格式:权限修饰符类名(形参列表){}
3.一个类中定义的多个构造器,彼此构成重载
4.一旦我们显式的定义了类的构造器之后,系统就不再提供默认的空参构造器
5.一个类中,至少会有一个构造器。
赋值顺序
截止到目前,我们讲到了很多位置都可以对类的属性赋值。现总结这几个位置,并指明赋值的先后顺序。
赋值的位置:
①默认初始化
②显式初始化
③构造器中初始化
④通过“对象.属性“或“对象.方法”的方式赋值
赋值的先后顺序:
①-②-③-④
this关键字的使用:
1.this可以用来修饰 调用:属性、方法、构造器
2.this修饰属性和方法:
this理解为:当前对象或当前正在创建的对象
2.1 在类的方法中,我们可以使用"this.属性"或"this.方法"的方式,调用当前对象属性或方法。但是,通常情况下,我们都选择省略"this."。特殊情况下,如果方法的形参和类的属性同名时,我们必须显式的使用"this.变量"的方式,表明此变量是属性,而非形参。
2.2在类的构造器中,我们可以使用"this.属性“或"this.方法"的方式,调用当前正在创建的对象属性或方但是,通常情况下,我们都选择省略"this."。特殊情况下,如果构造器的形参和类的属性同名时,我们必须显式的使用"this.变量"的方式,表明此变量是属性,而非形参。
3. this调用构造器
我们在类的构造器中,可以显式的使用"this(形参列表)"方式,调用本类中指定的其他构造器构造器中不能通过"this(形参列表)"方式调用自己
如果一个类中有n个构造器,则最多有n -1构造器中使用了"this(形参列表)"规定:"this(形参列表)"必须声明在当前构造器的首行
构造器内部,最多只能声明一个"this(形参列表)",用来调用其他的构造器
一、package关键字的使用(命名空间)
1.为了更好的实现项目中类的管理,提供包的概念
2.使用package声明类或接口所属的包,声明在源文件的首行
3.包,属于标识符,遵循标识符的命名规则、规范(XXXyyyzzz)、“见名知意”
4.每"."一次,就代表一层文件目录。
补充:同一个包下,不能命名同名的接口、类。
不同的包下,可以命名同名的接口、类。
二: Import关键字使用
1.在源文件中使用import显式的导入指定包下的类或接口
2.声明在包的声明和类的声明之间。
3.如果需要导入多个类或接口,那么就并列显式多个import语句即可
4.举例:可以使用java.util.*的方式,一次性导入util包下所有的类或接口。
5.如果导入的类或接口是java.lang包下的,或者是当前包下的,则可以省略此import语句。
6.如果在代码中使用不同包下的同名的类。那么就需要使用类的全类名的方式指明调用的是哪个类。
7.如果已经导入java.a包下的类。那么如果需要使用a包的子包下的类的话,仍然需要导入。
8. import static组合的使用:调用指定类或接口下的静态的属性或方法
一些常用的包
1. java.lang----包含一些Java语言的核心类,如String、Math、Integer、System和Thread,提供常用功能
2. java.net----包含执行与网络相关的操作的类和接口。
3. java.io ----包含能提供多种输入/输出功能的类。
4. java.uti----包含一些实用工具类,如定义系统特性、接口的集合框架类、使用与日期日历相关的函数。
5. java.text----包含了一些java格式化相关的类
6. java.sql----包含了java进行JDBC数据库编程的相关类/接口
MVC(Module View Controller)