前言
什么是类?什么是对象?
对象当然不是指的你的女(男)朋友,而是指的一个物品或者人。
比如,你去洗衣服这个事件,有几个对象?4个,分别是人,衣服,洗衣粉,洗衣机,假定你就是那个人,那么你需要做的就是,把衣服给洗衣机,把洗衣粉给洗衣 机,这就是面向对象的整个过程,我们不需要去关心洗衣机到底怎么运行,也不需要关心你在拿衣服的时候做什么,我们只关心这个对象。
类指的就是你这个洗衣服这个事件,你洗衣服所有的过程都在这里面,被统称为洗衣服,这就是个类。
创建对象可以用下面这个图来表示
图纸代表的一个类,而第一栋楼代表的就是根据这个图纸创建出来的对象。
创建类
创建一个类,就相当于我们要去画那么一张施工图,需要有属性,比如楼层的长宽高等,一张图规定完属性之后,还要画构造图,建出来是什么样,如下:
class Build{//需要注意,类名的创建一定要使用大驼峰
public int length=10;
public int width=9;
public int height=20;
//前面的在类里面被称为属性,也叫做普通成员变量
public void apartment(){
System.out.println("公寓"+length+width+height);
}
public void officeBuilding(){
System.out.println("写字楼"+length+width+height);
}
//上面的就是要建出来什么,也就是类里面的普通成员方法,描述类要做什么
}
创建对象
对象通过类实例化而来,下面我们来看一个实例化的例子
public class Main{
public static void main(String[] args){
//Build build=null;
//这里这个是指创建这么一个biuld 变量不指向任何对象
Build build=new Build();
//这里第一个Build代表的是一个类型,和 int a=10 中的 int 意义一样
//实例化对象是通过 new 这个关键字来实现的
System.out.println(build.length);
//普通成员变量的访问方式我们是通过对象的引用来访问的
build.apartment();
}
//对象的创建我们从上面的图可以看出可以创建多个对象
//所以,我们可以写出如下代码
Build build1=new Build();
Build build2=new Build();
Build build3=new Build();
Build build4=new Build();
Build build5=new Build();
//一个变量不能同时指向多个对象
build5=new Build();
build5=new Build();
build5=new Build();
build5=new Build();
//表示build6这个引用 指向build5这个引用 所指向的对象
Build build6=build5;
}
当然我们说在类里面创建这么一个属性是不方便的
因为你创建的这个属性已经被你写死了,我们说工程建设他是灵活的,对吧?图纸也不可能只有一张,因此,我们写代码的时候常常这样去写
class Build{
public int length;
public int width;
public int height;
public void apartment(){
System.out.pirntln("公寓:"+"长:"+length+"宽:"+width+"高:"+height);
}
public void officeBuilding(){
System.out.pirntln("写字楼:"+"长:"+length+"宽:"+width+"高:"+height);
}
}
public class Main{
public static void main(String[] args){
Build bd=new Build();
bd.length=10;
bd.width=29;
bd.height=30;
bd.apartment();
//这样的赋值方式使得我们的代码更加灵活,不在局限于某一个数值
Build bd1=new Build();
bd.length=10;
bd.width=28;
bd.height=90;
bd.apartment();
}
}
我们创建的这个对象它是被存放在堆区上面的,而我们创建的变量bd和bd1是存放在主函数的栈上面的,而我们的变量里面存放是堆区的地址,所以我们又称这个变量为引用。
那么引用一定是在栈上吗?肯定不是,原因如下图所示
它在栈区上面创建了一个t变量,t指向new Main() 这个对象,在这个对象中,又有创建了一个变量person,person指向new Person() 这个对象,这个对象中存在Person这个类的属性,从上图我们不难看出引用不一定在栈上。
注意这里是变量不是地址。
静态成员变量和静态成员方法
前面我们反复提到了普通成员变量和普通成员方法,这里为什么用普通两个字俩强调呢?就是为了这里,静态成员变量和静态成员方法。
什么是静态成员变量和静态成员方法?
我们通常将被static修饰的成员变量和成员方法称为静态成员变量和静态成员方法,它被放在方法区
class Biu{
public static int a=10;
int b=20;
public static void eat(){
//this.b=10;error
//因为this,表示当前对象的引用,而被static 修饰的方法不依赖于对象
//所以它在这里报错了
System.out.println("正在吃东西!");
}
}
public class Main{
public static void main(String[] args){
Biu.a;
Biu.b;
}
}
我们可以发现,静态成员变量和静态成员方法他们不需要经过创建对象就可以直接调用,为什么?
原因在于被static修饰的变量和方法都是直接属于类的,他们可以直接由类名调用。
静态成员方法中不能直接调用普通方法,普通方法中不能定义静态变量,但是,在以下这种情况中,静态成员方法能调用普通方法。
讲完静态成员方法之后,我们也该认识下类的最后一个方法了——构造方法
构造方法
所谓构造方法就是一种特殊方法, 使用关键字new实例化新对象时会被自动调用, 用于完成初始化操作。
构造方法语法规则:
1.方法名称必须与类名称相同
2.构造方法没有返回值类型声明
3.每一个类中一定至少存在一个构造方法(没有明确定义,则系统自动生成一个无参构造)
如下:
class Person{
private int age;
private String name;
public Person(){
this.age=10;
this.name="zg";
}
public Person(int age,String name){
this.age=age;
this.name=name;
}
public void show(){
System.out.println("name:"+name+"age:"+age);
}
}
public class Main{
public static void main(String[] args){
Person person=new Person();
person.show();
Person person1=new Person("zhangfei",80);
person1.show();
}
}
this使用方法:
this.data 调用当前对象的属性
this.func() 调用当前对象的方法
this() 调用当前对象的其他构造方法
示例如下:
class Person{
public int a=10;
public Person(){
this.Person(10);
this(10,10);
System.out.pirntln("不带参数构造");
}
public Person(int a){
this.a=a;
System.out.println("带一个参数构造");
}
public Person(int a,int b){
System.out.println("带两个参数构造");
}
}
在讲完类的几个方法和属性之后,我们就来到了本章末了——代码块
代码块
什么是代码块?
使用 {} 定义的一段代码.
根据代码块定义的位置以及关键字,又可分为以下四种:
普通代码块
构造块
静态块
同步代码块(我们这里暂且不谈)
普通代码块:定义在方法中的代码块
public class Main{
public static void main(String[] args) {
{ //直接使用{}定义,普通方法块
int x = 10 ;
System.out.println("x1 = " +x);
}
int x = 100 ;
System.out.println("x2 = " +x);
}
}
构造块:也叫实例代码块,定义在类中的代码块(不加修饰符)。代码块一般用于初始化实例成员变量。
class Person{
public Person() {
System.out.println("I am Person init()!");
}
//实例代码块
{
this.name = "bit";
this.age = 12;
this.sex = "man";
System.out.println("I am instance init()!");
}
}
静态代码块:使用static定义的代码块。一般用于初始化静态成员属性。
class Person{
static {
count = 10;//只能访问静态数据成员
System.out.println("I am static init()!");
}
}
静态代码块不管生成多少个对象,其只会执行一次,且是最先执行的。
静态代码块执行完毕后, 实例代码块(构造块)执行,再然后是构造函数执行。
示例: