类与对象
什么是类
Java语言把一组对象中相同属性和方法抽象到一个Java源文件就形成了类。是一组相关属性和行为的集合。可以看成是一类事物的模板,使用事物的属性特征和行为特征来描述该类事物。现实中,描述一类事物:属性:就是该事物的状态信息。行为:就是该事物能够做什么。
- 举例:小猫。 属性:名字、体重、年龄、颜色。
- 行为:走、跑、叫。
什么是对象
是一类事物的具体体现。对象是类的一个实例,必然具备该类事物的属性和行为。现实中,一类事物的一个实例:一只小猫。
举例:一只小猫。属性:tom、5kg、2 years、yellow。 行为:溜墙根走、蹦跶的跑、喵喵叫。
类与对象的关系
所有的事物都可以看做是一个对象(万物皆对象),是对象就具有一定的属性和功能,这些对象是可以建立起联系的,而且这些对象是由类来构造的。类是具有属性和方法的一组对象的集合,对象是实际存在的该类事物的个体
在面向对象中,类和对象是最基本和最重要的组成单元。类实际上是表示一个客观世界某类群体的一些基本特征抽象,对象就表示一个个具体的东西,对象是以类模板创建的。类是创建对象的模板,确定对象将会拥有的属性和方法。
在面向对象程序设计中,类是一个独立的单位,它有一个类名,其内部包括成员变量,用于描述对象的属性;还包括类的成员方法,用于描述对象的行为。在Java程序设计中,类被认为是一种抽象数据类型,这种数据类型,不但包括数据,还包括方法。这大大地扩充了数据类型的概念。
类是一个抽象的概念,要利用类的方式来解决问题,必须用类创建一个实例化的类对象,然后通过类对象去访问类的成员变量,去调用类的成员方法来实现程序的功能。这如同“汽车”本身是一个抽象的概念,只有使用了一辆具体的汽车,才能感受到汽车的功能。
一个类可创建多个类对象,它们具有相同的属性模式,但可以具有不同的属性值。Java程序为每一个类对象都开辟了内存空间,以便保存各自的属性值。对象与对象之间也可以相互联系和相互作用,我们把这种方式称为“消息”。 一个消息主要由5部分组成:发送消息的对象、接收消息的对象、消息传递办法、消息内容(参数)、消息反馈。
类是对象的抽象化;对象是类的具体化。图纸是类,根据图纸制作的东西就是对象. 对象同时具有属性和方法两项特性。
举个简单的例子:兰博基尼跑车,在工厂里首先要由设计师设计出一个汽车图纸,然后再根据图纸去生产兰博基尼,这样生产出来的每一辆跑车结构和功能都是一样的。但是不同的款式有不同的特征,比如车的颜色,内部装饰,马力等。在这个例子中,设计图纸就是一个类,它规定看跑车应该拥有的基本部件。而根据这张图纸生产出来的每一辆跑车就是一个个实时存在的对象。它们的初始状态是一模一样的,如果其中某一辆颜色,发动机重新改了之后并不影响其他的跑车
类的定义
定义一个类的步骤:
1、定义类名(关键字class引入类的定义,符合标识符命名规范,首字母大写,多个单词每个单词首字母都要大写);
2、定义类的属性(访问控制符,类型,属性名);
3、定义类的方法(访问控制符,访问修饰符,返回值,参数(类型,属性名))。
定义一个类的步骤:1、定义类名;2、定义类的属性;3、定义类的方法
public class 类名 { }
关键字class引入类的定义。
类名要符合标识符命名规范。
public class ClassName {
//成员变量
//成员方法
}
在类中定义其实都称之为成员。成员有两种:
1:成员变量:其实对应的就是事物的属性,在类中,方法外。
2:成员方法:其实对应的就是事物的行为,只不过把static去掉。
所以,其实定义类,就是在定义成员变量和成员方法。但是在定义前,必须先要对事物进行属性和行为的分析,才可以用代码来体现。
public class Student {
//成员变量
String name;//姓名
int age;//年龄
//成员方法
//学习的方法
public void study() {
System.out.println("好好学习,天天向上");
}
//吃饭的方法
publicvoid eat() {
System.out.println("学习饿了要吃饭");
}
}
类中怎么没有定义主方法呢?
注意:主方法的存在,仅为该类是否需要独立运行,如果不需要,主方法是不用定义的。
主方法的解释:保证所在类的独立运行,是程序的入口,被jvm调用。
public static void main (String[] args){
//执行内容
}
Public:访问权限最大。
static:不需要对象,直接类名即可。
void:主方法没有返回值。
Main:主方法特定的名称。
(String[] args):主方法的参数,是一个字符串数组类型的参数,jvm调用main方法时,
传递的实际参数是 new String[0]。
jvm默认传递的是长度为0的字符串数组,我们在运行该类时,
也可以指定具体的参数进行传递。可以在控制台,运行该类时,
在后面加入参数。参数之间通过空格隔开。jvm会自动将这些
字符串参数作为args数组中的元素,进行存储。
标准代码——JavaBean
JavaBean 是 Java语言编写类的一种标准规范。符合 JavaBean 的类,要求类必须是具体的和公共的,并且具有无参数的构造方法,提供用来操作成员变量的 set 和 get 方法。
public class ClassName{
//成员变量
//构造方法
//无参构造方法【必须】
//有参构造方法【建议】
//成员方法
//getXxx()
//setXxx()
}
编写符合 JavaBean 规范的类,以学生类为例,标准代码如下
public class Student {
//成员变量
private String name;
private int age;
//构造方法
public Student() {}
public Student(String name,int age) {
this.name = name;
this.age = age;
}
//成员方法
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
}
测试类,代码如下:
public class TestStudent {
public static void main(String[] args) {
//无参构造使用
Student s= new Student();
s.setName("柳岩");
s.setAge(18);
System.out.println(s.getName()+"‐‐‐"+s.getAge());
//带参构造使用
Student s2= new Student("赵丽颖",18);
System.out.println(s2.getName()+"‐‐‐"+s2.getAge());
}
}
对象的使用
对象初始化过程
用new创建并初始化对象步骤:
给对象的实例变量分配内存空间,默认初始化成员变量;
成员变量声明时的初始化;
初始化块初始化;(
初始化块:就是在类中用一对大括号括起来的代码块,语法形式如下:{ //代码块 }
)
构造方法初始化
通过new关键字创建对象。创建对象又称实例化对象。
this在实例方法中通常被省略,除非实例方法中包含与成员变量同名的局部变量时,访问成员变量需要使用this。
创建对象:类名 对象名 = new 类名();
使用对象访问类中的成员:使用点”.”这个符号 对象名.成员变量; 对象名.成员方法();
Student lisi = new Student();
使用”.”运算符访问对象的属性和方法。
lisi.属性 = 值;
lisi.方法名();
/*
初始化块初始化:名字雷神 年龄2 性别1 年级6
有参构造方法初始化
名字王云 年龄22 性别1 年级4
*/
class Student {
String stuName = ""; // 姓名
int stuAge = -1 ;// 年龄
int stuSex = -1; // 性别
int stuGrade = -1; // 年级
// 对象的初始化块初始化
{
this.stuName = "雷神"; // 姓名
this.stuAge = 2 ;// 年龄
this.stuSex = 1; // 性别
this.stuGrade = 6; // 年级
System.out.println("初始化块初始化:名字"+this.stuName+" 年龄"+this.stuAge+" 性别"+this.stuSex+" 年级"+this.stuGrade);
}
// 无参构造方法初始化
public Student() {
System.out.println("无参构造方法初始化");
}
// 有参构造方法初始化
public Student(String stuName, int stuAge, int stuSex, int stuGrade) {
System.out.println("有参构造方法初始化");
this.stuName = stuName; // 姓名
this.stuAge = stuAge;// 年龄
this.stuSex = stuSex; // 性别
this.stuGrade = stuGrade; // 年级
}
}
public class TestStudent {
public static void main(String [] args) {
// 构造方法初始化在对象的初始化块初始化之后
Student student = new Student("王云", 22, 1, 4);
System.out.println("名字"+student.stuName+" 年龄"+student.stuAge+" 性别"+student.stuSex+" 年级"+student.stuGrade);
}
}
成员变量的默认值
数据类型 | 默认值 | |
基本类型 | 整数(byte,short,int,long) | 0 |
浮点数(float,double) | 0.0 | |
字符(char) | '\u0000' | |
布尔(boolean) | false | |
引用类型 | 数组,类,接口 | null |
成员变量和局部变量的区别:
1:成员变量直接定义在类中。
局部变量定义在方法中,参数上,语句中。
2:成员变量在这个类中有效。
局部变量只在自己所属的大括号内有效,大括号结束,局部变量失去作用域。
3:成员变量存在于堆内存中,随着对象的产生而存在,消失而消失。
局部变量存在于栈内存中,随着所属区域的运行而存在,结束而释放。
4:初始化值的不同
成员变量:有默认值
局部变量:没有默认值。必须先定义,赋值,最后使用
5:生命周期不同
成员变量:随着对象的创建而存在,随着对象的消失而消失
局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
匿名对象使用场景:
java中匿名对象“只在堆内存中开辟空间,而没有在栈内存的引用”,堆中存放具体数据,栈中存放你所命名的变量名字
普通对象:
A a = new A();//a存放在栈上,new A()产生的对象在堆上,a存放的是new出来的对象在堆内存中的地址,也就是栈上的这个a是指向新new出来的对象的,a就是new出来的对象的引用。
匿名对象:
在堆上生成了对象,但是在栈上没有某个变量指向它。
1:当对方法只进行一次调用的时候,可以使用匿名对象。
2:当对象对成员进行多次调用时,不能使用匿名对象。必须给对象起名字。
在类中定义其实都称之为成员。成员有两种:
1:成员变量:其实对应的就是事物的属性。
2:成员函数:其实对应的就是事物的行为。
所以,其实定义类,就是在定义成员变量和成员函数。但是在定义前,必须先要对事物进行属性和行为的分析,才可以用代码来体现。
通过new关键字创建对象。创建对象又称实例化对象。
this在实例方法中通常被省略,除非实例方法中包含与成员变量同名的局部变量时,访问成员变量需要使用this。
Student lisi = new Student();
使用”.”运算符访问对象的属性和方法。
lisi.属性 = 值;
lisi.方法名();
private int age;//私有的访问权限最低,只有在本类中的访问有效。
注意:私有仅仅是封装的一种体现形式而已。
创建一个对象都在内存中做了什么事情?
Person p = new Person();
1:先将硬盘上指定位置的Person.class文件加载进内存。
2:执行main方法时,在栈内存中开辟了main方法的空间(压栈-进栈),然后在main方法的栈区分配了一个变量p。
3:在堆内存中开辟一个实体空间,分配了一个内存首地址值。new
4:在该实体空间中进行属性的空间分配,并进行了默认初始化。
5:对空间中的属性进行显示初始化。
6:进行实体的构造代码块初始化。
7:调用该实体对应的构造方法,进行构造方法初始化。()
8:将首地址赋值给p ,p变量就引用了该实体。(指向了该对象)
私有的成员:其他类不能直接创建对象访问,所以只有通过本类对外提供具体的访问方式来完成对私有的访问,可以通过对外提供函数的形式对其进行访问。
好处:可以在函数中加入逻辑判断等操作,对数据进行判断等操作。
总结:开发时,记住,属性是用于存储数据的,直接被访问,容易出现安全隐患,所以,类中的属性通常被私有化,并对外提供公共的访问方法。
这个方法一般有两个,规范写法:对于属性 xxx,可以使用setXXX(),getXXX()对其进行操作。
类中怎么没有定义主函数呢?
注意:主函数的存在,仅为该类是否需要独立运行,如果不需要,主函数是不用定义的。
主函数的解释:保证所在类的独立运行,是程序的入口,被jvm调用。
成员变量和局部变量的区别:
1:成员变量直接定义在类中。
局部变量定义在方法中,参数上,语句中。
2:成员变量在这个类中有效。
局部变量只在自己所属的大括号内有效,大括号结束,局部变量失去作用域。
3:成员变量存在于堆内存中,随着对象的产生而存在,消失而消失。
局部变量存在于栈内存中,随着所属区域的运行而存在,结束而释放。
构造函数:
用于给对象进行初始化,是给与之对应的对象进行初始化,它具有针对性,函数中的一种。
特点:
1:该函数的名称和所在类的名称相同。
2:不需要定义返回值类型。
3:该函数没有具体的返回值。
什么是构造方法
构造方法负责初始化类中的实例变量。非“类变量”
构造方法是一种特殊的方法,这种方法必须满足以下语法规则:
构造方法必须与类名相同;
不包含返回值类型描述部分
记住:
所有对象创建时,都需要初始化才可以使用。
构造方法是一个类对象实例化的起点,实例化的目的是为了给类成员初始化,所以引用的成员应该是常量而不是变量,不能将成员作为参数引用。
注意事项:
一个类在定义时,如果没有定义过构造函数,那么该类中会自动生成一个空参数的构造函数,为了方便该类创建对象,完成初始化。如果在类中自定义了构造函数,那么默认的构造函数就没有了。
显式构造方法
创建类时,如果没有显式定义构造方法,则该类会存在一个默认的无参构造方法;
可以在类中声明一个或多个有参构造方法,但每个构造方法在参数个数或参数数据类型上要有所差别:
一个类中,可以有多个构造函数,因为它们的函数名称都相同,所以只能通过参数列表来区分。所以,一个类中如果出现多个构造函数。它们的存在是以重载体现的。
如果类中存在显式构造方法,则默认的无参构造方法将不复存在,除非显式定义无参构造方法:
构造函数和一般函数有什么区别呢?
1:两个函数定义格式不同。
2:构造函数是在对象创建时,就被调用,用于初始化,而且初始化动作只执行一次。
一般函数,是对象创建后,需要调用才执行,可以被调用多次。
什么时候使用构造函数呢?
分析事物时,发现具体事物一出现,就具备了一些特征,那就将这些特征定义到构造函数内。
构造代码块和构造函数有什么区别?
构造代码块:是给所有的对象进行初始化,也就是说,所有的对象都会调用一个代码块。只要对象一建立。就会调用这个代码块。
构造函数:是给与之对应的对象进行初始化。它具有针对性。
父类对子类构造方法的影响
1、如果父类拥有无参构造方法(无论隐式的还是显式的)且子类中的构造方法又没有明确指定调用父类的哪个构造方法,则子类的构造方法使用super()隐式调用父类的无参构造方法。
当实例化子类时,先实例化父类
如果子类构造方法使用隐式方式调用父类的无参构造方法,则子类中构造方法之间可以使用this进行调用
2、如果父类没有无参构造方法(无论隐式的还是显式的),则要求子类构造方法必须直接或间接指定调用父类哪个构造方法并且放在有效代码第一行
This:
代表对象。就是所在函数所属对象的引用。
this到底代表什么呢?
哪个对象调用了this所在的函数,this就代表哪个对象,就是哪个对象的引用。this代表对当前对象的一个引用
开发时什么时候使用this呢?
在定义功能时,如果该功能内部使用到了调用该功能的对象,这时就用this来表示这个对象。
this 还可以用于构造函数间的调用。
调用格式:this(实际参数);
this对象后面跟上 . 调用的是成员属性和成员方法(一般方法);
this对象后面跟上 () 调用的是本类中的对应参数的构造函数。
注意:
用this调用构造函数,必须定义在构造函数的第一行。因为构造函数是用于初始化的,所以初始化动作一定要执行。否则编译失败。
this实现一个类中构造方法之间的调用
类中可以有多个构造方法,构造方法之间可以通过this实现调用,但必须将调用构造函数代码写在有效代码的第一行:
普通方法不能用this调用构造方法
普通方法不能使用this调用类中构造方法
对象初始化过程
用new创建并初始化对象步骤:
给对象的实例变量分配内存空间,默认初始化成员变量;
成员变量声明时的初始化;
初始化块初始化;
构造方法初始化
初始化块:就是在类中用一对大括号括起来的代码块,语法形式如下:
{
//代码块
}
创建一个对象都在内存中做了什么事情?
Person p =new Person();
1:先将硬盘上指定位置的Person.class文件加载进内存。
2:执行main方法时,在栈内存中开辟了main方法的空间(压栈-进栈),然后在main方法的栈区分配了一个变量p。
3:在堆内存中开辟一个实体空间,分配了一个内存首地址值。new
4:在该实体空间中进行属性的空间分配,并进行了默认初始化。
5:对空间中的属性进行显示初始化。
6:进行实体的构造代码块初始化。
7:调用该实体对应的构造函数,进行构造函数初始化。()
8:将首地址赋值给p ,p变量就引用了该实体。(指向了该对象)