类和对象
类和对象的关系
类就是一类对象的总称
对象就是这个类具体化的一个实例
Java不同于c语言(面向过程),它是基于面向对象的,关注的是对象
关于面向对象和面向过程,举一个生活中的例子帮助理解
洗衣服这个事情,在c语言中,我们关注的是这个过程,人将洗衣液和衣服放进洗衣机,洗衣机进行洗涤脱水
在Java中我们只需要关注两个对象,人和洗衣机,具体他们是如何做的这个过程我们不关注
类和类的实例化
基本语法
//创建类
class <class_name>{
field;//成员属性
method;//成员方法
}
//实例化对象
<class_namme> <对象名>=new <class_name>();
ps:class为定义类的关键字,class_name为类的名字,{}为类的主体
成员属性:类中的元素,成员方法:类中的函数
举个例子:
创建一个简单的类
public class test {
class person {
public int age;//成员属性
public String name;
public String sex;
public void eat(){//成员方法
System.out.println("吃饭!");
}
public void sleep(){
System.out.println("睡觉!");
}
public void play(){
System.out.println("玩儿!");
}
}
}
与之前的方法不同的是,这里不带static
类的实例化
用类创建对象的过程就叫做类的实例化
1、类就是一个模型,限定了类有哪些成员
2、一个类可以实例化很多对象,实例化的对象占用实际的物理空间,存储类成员变量
就相当于我们有了一个设计图纸(类)可以依照这个图纸建造出很多房子(对象)
class Person {
public int age;//成员属性
public String name;
public String sex;
public void eat(){//成员方法
System.out.println("吃饭!");
}
public void sleep(){
System.out.println("睡觉!");
}
public void play(){
System.out.println("玩儿!");
}
}
public class test {
public static void main(String[] args) {
Person person=new Person();//通过new实例化对象
person.eat();//通过对象的引用调用成员方法
person.play();
System.out.println(person.name);
System.out.println(person.age);
Person person2=new Person();//可以实例化很多对象
}
}
ps:
1、new关键字用于创建一个对象的实例
2、使用. 访问对象中的属性和方法,访问既包含读又包含写
3、同一个类可以创建多个实例
4、对于一个对象的字段如果没有显示设置初始值,就会被默认一个初值
默认规则:数字类型默认0;boolean类型默认false;自定义类型默认null,空引用表示不引用任何对象,对null进行.操作就会发生异常
类的成员
包括字段(成员变量)、方法、代码块、内部类、接口等
字段初始化
直接在类里面初始化
class Person {
public int age=21;//成员属性
public String name="张三";
public String sex;
public void eat(){//成员方法
System.out.println("吃饭!");
}
public void sleep(){
System.out.println("睡觉!");
}
public void play(){
System.out.println("玩儿!");
}
}
public class test {
public static void main(String[] args) {
Person person=new Person();//通过new实例化对象
person.eat();//通过对象的引用调用成员方法
person.play();
System.out.println(person.name);
System.out.println(person.age);
Person person2=new Person();//可以实例化很多对象
}
}
实例化多个对象
static 关键字
作用:
1、修饰属性(Java静态属性和类相关,和具体的事例无关,即同一个类中的不同实例共用同一个静态属性)
2、修饰方法(静态方法属于类,不属于对象,所以可以直接调用静态方法,无需创建类的实例;静态方法可以访问静态数据成员,也可以更改静态数据成员的值;但是,在静态方法中不能访问非静态数据成员)
3、代码块
4、修饰类
static 修饰的成员变量在方法区上只存一次,供所有的类使用,所有static修饰的都不依赖于对象
在Java中static只能修饰成员变量和成员方法,不能修饰局部变量
方法
用于描述一个对象的行为
class Person {
public int age=21;//成员属性
public String name="张三";
public String sex;
public void show(){
System.out.println("我叫"+name+"今年"+age+"岁");
}
}
public class test {
public static void main(String[] args) {
Person person=new Person();
person.show();
}
}
封装
本质:让类的调用者不必太多了解类的的实现者是如何实现类的,可以使用即可
private 实现封装
Java中访问控制关键字:Java中提供了三个关键字在类的内部设置边界,控制类的访问权限,分别是:public、protected、private。这些访问的指定词决定了紧跟其后的被定义的东西可以被谁使用。Java还有一种默认的访问权限,在不指定任何关键字的情况下,这种权限将发挥作用,它是一种包的访问权限,即在当前包中的任何元素可以访问。
private实现封装的例子:
不用private
class Person {
public int age=21;//成员属性
public String name="李思";
public String sex;
public void show(){
System.out.println("我叫"+name+"今年"+age+"岁");
}
}
public class test {
public static void main(String[] args) {
Person person=new Person();
person.show();
}
}
这种调用需要调用者清楚类中是如何实现的
使用private修饰,提供一个调用方法便可不需要知道类的内部实现
class Person {
private int age=21;//成员属性
private String name="李思";
private String sex;
public void show(){
System.out.println("我叫"+name+"今年"+age+"岁");
}
}
public class test {
public static void main(String[] args) {
Person person=new Person();
person.show();
}
}
getter和setter方法
上面的例子,我们知道,如果用private修饰字段,那就无法直接在去使用这个字段
那我们如果想要去修改这个private属性,就需要用到getter/setter方法
class Person {
private int age;//成员属性
private String name;
private String sex;
public void setName(String name){
//name=name;相当于给name赋值
this.name=name;
}
public String getName(){
return name;
}
public void show(){
System.out.println("我叫"+name+"今年"+age+"岁");
}
}
public class test {
public static void main(String[] args) {
Person person=new Person();
person.setName("小花");
String name=person.getName();
System.out.println(name);
person.show();
}
}
在上面的例子中,
getName就是getter方法,表示获取这个成员的值
setName就是setter方法,表示设置这个成员的值
注意:
1、当set方法的形参名字和类中成员属性的名字一样时,如果不使用this,相当于自赋值,this表示当前实例的引用
2、不是所有字段都需要提供这两个方法,依据实际情况判断
3、在idea中可使用alt+insert(alt+f12),快速生成这两个方法,在vscode鼠标右键、源代码操作中自动生成这两个方法
构造方法
基本语法
构造方法是一种特殊的方法,使用关键字new实例化新对象时会被自动调用,用于对象的初始化
Person person=new Person();//调用不带参数的构造方法,当前类不提供任何构造方法时,编译器默认提供无参的构造方法
实例化对象的本质:1、为对象分配内存 2、调用对象合适的构造方法
语法规则
1、方法名必须和类名相同
2、没有返回值类型声明
3、每一个类中一定至少存在一个构造方法(没有明确定义时,系统自动生成一个无参的构造方法,类中定义了,默认的自然就不会生成)
4、构造方法同样支持重载
class Person {
private int age;//成员属性
private String name;
private String sex;
public Person(){
this.name="小明";
this.age=19;
this.sex="男";
}
public Person (String name,int age,String sex){
this.name=name;
this.age=age;
this.sex=sex;
}
public void show(){
System.out.println("我叫"+name+"今年"+age+"岁");
}
}
public class test {
public static void main(String[] args) {
Person person1=new Person();
person1.show();
Person person2=new Person("小红",12,"女");
person2.show();
}
}
person1调用默认无参的构造方法,person2调用有三个参数的构造方法
关键字this
this是一个引用,表示“当前对象的引用”,可以借助this访问对象的字段和方法,通常可以省略
用法:
1、this.成员变量:访问类中的成员变量
2、this.成员方法:访问类中的成员方法
3、this():调用本类其他构造方法
注意:
1、this调用构造方法一定要写在第一行
2、在静态方法中不能使用this,因为静态方法不需要实例化,就没有“对象”
关于引用:
1、引用如果在栈上,说明该引用是局部变量,在Java中,数组是在堆上的,但是数组也是引用
2、引用只能指向对象,并且一个引用只能指向向一个对象
3、一个引用赋值为null,说明当前引用不指向任何对象
认识代码块
字段的初始化方式:
1、就地初始化
2、使用构造方法初始化
3、使用代码块初始化
前面已将介绍了前两者,下面看看第三种方式
什么是代码块
使用{}定义的一段代码
根据代码块定义的位置以及关键字,分为以下几种:
1、普通代码块
2、构造块
3、静态块
4、同步代码块(多线程)
普通代码块
定义在方法中的代码块
public static void main(String[] args) {
int x=10;
System.out.println("x1="+x);
}
构造块
定义在类中的代码块 (不加修饰符),也称“实例代码块”。一般用于初始化实例成员变量
class Person {
private int age;//成员属性
private String name;
private String sex;
public Person(){
System.out.println("构造函数!");
}
{
this.name="小红";
this.age=10;
this.sex="女";
System.out.println("实例代码块!");
}
public void show(){
System.out.println("其他方法!");
}
}
public class test {
public static void main(String[] args) {
Person person=new Person();
person.show();
}
}
执行顺序:实例代码块优先于构造函数优先于其他方法
静态代码块
使用static定义的代码块,一般用于初始化静态成员属性
class Person {
private int age;//成员属性
private String name;
private String sex;
private static int count=10;//静态成员变量,存放在方法区,由类共享这一个数据
{
this.name="小红";
this.age=10;
this.sex="女";
System.out.println("实例代码块!");
}
public void show(){
System.out.println("其他方法!");
}
static{
count=100;
System.out.println("count ="+count+"静态代码块!");
}
public Person(){
System.out.println("构造函数!");
}
}
public class test {
public static void main(String[] args) {
Person person=new Person();
person.show();
}
}
注意:
1、静态代码块不管生成多少对象,只会执行一次,并且是最先执行的
2、静态代码块执行完后,实例代码块执行,再是构造函数
toString方法
public class test {
public static void main(String[] args) {
Person person=new Person();
person.show();
System.out.println(person);//这里打印了一个地址的哈希值,是因为调用了object的toSrting方法
}
}
可以使用toString方法将那个对象自动转化成字符串
class Person {
private int age;//成员属性
private String name;
private String sex;
private static int count=10;//静态成员变量,存放在方法区,由类共享这一个数据
public Person (String name,int age,String sex){
this.name=name;
this.age=age;
this.sex=sex;
}
public void show(){
System.out.println("我是"+name+"今年"+age+sex);
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
'}';
}
}
public class test {
public static void main(String[] args) {
Person person=new Person("李思",18,"女");
person.show();
System.out.println(person);
}
}
注意;
1、toString方法在println使用时自动调用
2、将对象转化为字符串的这个过程就叫序列化
3、toString是object类提供的方法,我们自己创建的Person类默认继承object类,可以重写toString方法实现我们自己版本的转换字符串方法
4、@Override在Java中称为“注释”,这里表示以下实现toString方法是重写了父类的方法
5、生成toString方法快捷键:alt+f12(insert)或者右键
选中需要里面的属性即可
匿名对象
匿名顾名思义就是没有名字的对象
1、没有引用的对象成为匿名对象
2、匿名对象只能在创建对象时使用
3、如果一个对象只是使用一次,后面不需要用了,就可以使用匿名对象(“每用一次,每new一次”)
class Person {
private int age;//成员属性
private String name;
private String sex;
private static int count=10;//静态成员变量,存放在方法区,由类共享这一个数据
public Person (String name,int age,String sex){
this.name=name;
this.age=age;
this.sex=sex;
}
public void show(){
System.out.println("我是"+name+"今年"+age+sex);
}
}
public class test {
public static void main(String[] args) {
new Person("大为",23,"男").show();
}
}
重点总结
1、一个类就相当于一个模板,他可以实例化很多对象
2、类中定义的属性:类属性(静态),对象属性(对象引用)。被static修饰的是类属性(变量和方法),他们不依赖于对象,使用类名直接使用或者调用
3、静态代码块是共享数据,优先于实例代码块执行,实例代码块优先构造函数执行
4、this关键字代表当前对象的引用,并不是当前对象