类与对象的定义与使用:
类是共性的概念,而对象是具体的,可以使用的事物。
类是生产对象的蓝图,先有类才可以产生对象。对象的所有属性与行为,一定在类中进行了完整定义。
类中的组成:
1.属性(变量,描述每个对象的具体特点)
2.方法(操作的行为)
定义一个类的语法如下:
class 类名称{
属性1;
属性2;
...
方法1(){}
方法2(){}
...
}
类中的属性与方法只能通过对象调用 。
对象产生的语法:
类名称 对象名称 = new 类名称();
对象内存分析
栈内存(虚拟机局部变量表):存放的是局部变量(各种基本数据类型,对象引用-对象名字)
堆内存:保存的是真正的数据。即对象的属性信息。
垃圾空间:没有任何栈内存指向的堆内存空间。
举个栗子:
class Student{
private String name;
private int age;
public Student(String name, int age){ //构造方法
this.name = name;
this.age = age;
}
public void getStudentInfo(){ //普通方法
System.out.println("姓名:"+this.name+",年龄:"+this.age);
}
}
public class Test{
public static void main(String[] args){
Student stu = new Student("李",20);
stu.getStudentInfo();
}
}
内存图如下:
private实现封装:
封装是面向对象里最复杂的概念,使用private关键字实现的封装处理只是封装的第一步。
private实现对类中属性的封装,:此时要想访问被封装的属性,必须提供getter与setter方法:
setter方法:主要进行属性内容的设置与修改
getter方法:主要进行属性内容的取得
举例说明:
class Student{
private String name;
private int age;
public void setName(String n){
name = n;
}
public String getName(){
return name;
}
public void setAge(int a){
if(a > 0 && a < 150){
age = a;
}else{
age = 0;
}
}
public int getAge(){
return age;
}
public void getStudentInfo(){
System.out.println("姓名:"+name+" 年龄:"+age);
}
}
public class Test{
public static void main(String[] args){
Student stu = new Student();
stu.setName("张三");
stu.setAge(20);
stu.getStudentInfo();
}
}
运行结果:
构造方法:
我们先回忆一下产生对象的语法:
类名称 对象名称 = new 类名称();
现在我们来做如下分析:
通过以上分析可知,所谓的构造方法就是使用关键字new实例化新对象是来调用的操作方法。对于构造方法的定义,要遵循一下原则:
a.构造方法名称必须与类名称相同
b.构造方法中没有返回值类型声明(不是没有返回值)
c.每个类中一定至少存在一个构造方法,如果没有明确定义,系统会自动生成无参构造。若在类中自定义了构造方法,则系统不再默认生成无参构造。
构造方法无返回值,为什么没有void声明?
在回答这个问题前,我们先看看类中的组成:属性,构造方法,普通方法
1.属性是在对象开辟堆内存时开辟的空间
2.构造方法是在使用new之后调用的
3.普通方法是在空间开辟了,构造方法执行之后可以多次调用的
public void Student(){}//命名不标准的普通方法
public Student(){}//无参构造
因此,编译器是根据程序结构来区分不同方法和构造方法的,所以在构造方法前没有返回值类型声明。
构造方法重载:参数类型或个数不同。
public Student(){
System.out.println("这是无参构造");
}
public Student(int a){
age = a;
System.out.println("这是有参构造");
}
在进行类型定义时: 1.定义属性 -> 2.定义构造方法 -> 3.定义普通方法
this关键字:
1.this调用本类属性
class Student{
private String name;
private int age;
public Student(String name, int age){
name = name;
age = age;
}
public void getStudentInfo(){
System.out.println("姓名:"+name+" 年龄:"+age);
}
}
public class Test{
public static void main(String[] args){
Student stu = new Student("张三",20);
stu.getStudentInfo();
}
}
运行结果:
我们发现,当参数与类中属性同名时,类中属性无法被正确赋值,例如代码中的name,编译器只能根据你在使用的位置(name = name)向上查找,找到最近的name就以为是你需要的,但是你需要的是类中的属性。此时,我们加上this关键字,代表你需要的是当前对象的属性,就可以真确赋值了。
运行结果:
2.this调用本类方法
this调用本类方法有两种情况:
a.调用普通方法:this.方法名(参数)
class Student{
private String name;
private int age;
public Student(String name, int age){
this.name = name;
this.age = age;
this.print();
}
public void getStudentInfo(){
System.out.println("姓名:"+name+" 年龄:"+age);
}
public void print(){
System.out.println("--------------------------");
}
}
public class Test{
public static void main(String[] args){
Student stu = new Student("张三",20);
stu.getStudentInfo();
}
}
运行结果:
b.调用构造方法: this(参数)
class Student{
private String name;
private int age;
public Student(){
System.out.println("*****产生一个新的Stuent对象*****");
}
public Student(String name){
this();//调用本类无参构造
this.name = name;
}
public Student(String name, int age){
this(name);//调用本类有参构造
this.name = name;
this.age = age;
}
public void getStudentInfo(){
System.out.println("姓名:"+name+" 年龄:"+age);
}
}
public class Test{
public static void main(String[] args){
Student stu1 = new Student();
Student stu2 = new Student("李四");
Student stu3 = new Student("张三",20);
stu1.getStudentInfo();
stu2.getStudentInfo();
stu3.getStudentInfo();
}
}
运行结果:
在Java中,支持构造方法的相互调用。
注意:
I.this调用构造方法必须放在构造方法首行
II.this调用构造方法不允许成环
3.使用this表示当前对象
class Student{
public void print(){
System.out.println("[print]方法"+this);
}
}
public class Test{
public static void main(String[] args){
Student stu1 = new Student();
System.out.println("[main]方法"+stu1);
stu1.print();
System.out.println("-------------------------------------");
Student stu2 = new Student();
System.out.println("[main]方法"+stu2);
stu2.print();
}
}
运行结果:
只要对象调用了本类中的方法,这个this就表示当前对象。
static关键字:
1.static属性(类属性)
static属性成为类属性,保存在全局数据区中(方法区--所有对象共享区域),通过类名调用,与对象实例化无关。
描述共享属性用static。
2.static方法(类方法)
使用static定义的方法,直接通过类名称访问。
class Student{
private static String school;
private String name;
private int age;
public Student(String name, int age){
this.name = name;
this.age = age;
}
public static void setSchool(String s){
school = s;
}
public void getStudentInfo(){
System.out.println("姓名:"+name+" 年龄:"+age+" 学校:"+school);
}
}
public class Test{
public static void main(String[] args){
Student.setSchool("理工大");
Student stu = new Student("张三",20);
stu.getStudentInfo();
}
}
运行结果:
关于static方法有以下两点说明:
a.所有的static方法不允许调用非static的定义的属性或方法
b.所有的非static方法允许访问static属性或方法
使用static定义方法只有一个目的:某些地方不希望受到类的控制,即可以在没有实例化对象的时候执行(广泛存在于工具类中)