面向对象(五) 面向对象编程就是拿东西来做对应的事,就比如人要洗衣服会拿洗衣机洗。
类和对象 类 :是对象共同特征的描述。对象 :是真实存在的具体东西。 在java中,必须先设计类,才能获得对象。 类是对象的抽象,对象是类的实例。
类的定义: 1 2 3 4 5 6 7 public class 类名{ 1.成员变量(代表属性,一般是名词) 2.成员方法(代表动作,一般是动词) 3.构造器 4.代码块 5.内部类 }
类的对象
类的使用 访问属性 : 对象名.成员变量访问行为 : 对象名.方法名(……)
定义类的注意事项 类名首字母建议大写,见名知意,驼峰模式。 一个java文件可定义多个class类,但只能一个类是public修饰,public修饰的类名必须成为代码文件名。 实际开发中建议一个文件定义一个class类。 成员变量的完整定义格式: 修饰符 数据类型 变量名称=初始值; 一般无需指定初始化值,存在默认值 用来描述一类事物的类,叫做:javabean类 。在javabean类 中,是不写main方法的。 编写main方法的类,叫做测试类 。可以在测试类中创建javabean类 的对象并进行复制调用
例子 1 2 3 4 5 6 7 8 9 10 11 12 13 //javabean类 //Student.java public class Student{ String name; String sex; int grade; public void play(){ System.out.println(name+"在玩"); } public void study(){ System.out.println(name+"在学习"); } }
1 2 3 4 5 6 7 8 9 10 11 //测试类 public class StudentTest{ public static void main(String[] args){ Student student=new Student(); student.name="张三"; student.sex="男"; student.grade=60; student.play(); student.study(); } }
封装 封装 便是告诉我们,如何正确设计对象的属性和方法。 对象代表什么,就要封装相应的数据,并提供数据相应的行为。
private关键字 private 是一个权限修饰符,可以修饰成员(成员变量和成员方法),被private修饰的成员只能在本类中才能访问。 针对private修饰的成员变量,若需被其他类使用,要提高响应的操作。 提供”setXXX(参数)”方法,用于给成员变量赋值,方法用public修饰。 提供”getXXX()”方法,用于获取成员变量的值,方法用public修饰。例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 //Student.java public class Student{ private String name; private String sex; private int grade; public void setName(String n){ name=n; } public String getName(){ return name; } public void setSex(String s){ sex=s; } public String getSex(){ return sex; } public void setGrade(int g){ if(g>=0 && g<=100){ grade=g; }else{ System.out.println("参数非法"); } } public int getGrade(){ return grade; } }
1 2 3 4 5 6 7 8 9 10 11 12 //StudentTest.java public class StudentTest{ public static void main(String[] args){ Student student=new Student(); student.setName("zhangsan"); student.setSex("男"); student.setGrade(56); System.out.println(student.getName()); System.out.println(student.getSex()); System.out.println(student.getGrade()); } }
this关键字 当成员变量和局部变量重名时,就会触发就近原则 (谁离我近,我就用谁)this 可以区别成员变量和局部变量。this的本质 :代表所在方法调用者的地址值
1 2 3 4 5 6 7 8 9 10 public class Student{ private int age;//成员变量 public void method(int age){ int age=10;//局部变量 System.out.println(age); //触发就近原则,打印局部变量age,10 System.out.println(this.age); //此时age是成员变量 } }
例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 //Student.java public class Student{ private String name; private String sex; private int grade; public void setName(String name){ this.name=name; } public String getName(){ return name; } public void setSex(String sex){ this.sex=sex; } public String getSex(){ return sex; } public void setGrade(int grade){ if(grade>=0 && grade<=100){ this.grade=grade; }else{ System.out.println("参数非法"); } } public int getGrade(){ return grade; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 //StudentTest.java public class StudentTest{ public static void main(String[] args){ Student student=new Student(); //this代表的是student的地址值 student.setName("zhangsan"); //this.name=name; //等号右边name遵循就近原则,为形参,接收zhangsan //等号左边this为student的地址值,取的成员变量name student.setSex("男"); student.setGrade(56); System.out.println(student.getName()); System.out.println(student.getSex()); System.out.println(student.getGrade()); } }
构造方法 构造方法 也就做构造器,构造函数。作用 :在创建对象时给成员变量进行赋值。分类 :无参数构造方法 和有参数构造方法
格式 1 2 3 4 5 6 7 8 9 10 11 public class 类名{ //空参构造方法 修饰符 类名(){ 方法体 } //带全部参数构造方法 修饰符 类名(参数){ 方法体; } }
特点
方法名与类名相同,大小写也一致
无返回值类型,也没有void
也不能由return带回结果数据
执行时机
创建对象时由虚拟机调用,不能手动调用构造方法
每创建一次对象,就会调用一次构造方法。
注意事项
构造方法的定义
若未定义构造方法,系统将给出一个默认的无参数构造方法
若定义了构造方法,系统不再给出默认的无参数构造方法
构造方法的重载
带参和无参构造方法,两者方法名相同,参数不同,称为构造方法的重载
无论是否使用,都尽量写无参和带参的构造方法
范例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 //javabean类 //Student.java 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; } }
1 2 3 4 5 6 7 8 9 //测试类 //StudentTest.java public class StudentTest{ public static void main(String[] args){ Student student=new Student("zhangsan",16); System.out.println(student.getName()); System.out.println(student.getAge()); } }
标准的javabean类
类名需见名知意。
成员变量使用private修饰
提供至少两种构造方法
成员方法
提供每一个成员变量的对应的setXXX()/getXXX()
若有其他行为,也写上
成员变量和局部变量的区别
类中位置不同:
成员变量在类中,方法外
局部变量在方法内,方法声明上
初始化值不同:
内存位置不同:
生命周期不同:
成员变量随着对象创建而存在,随着对象消失而消失
局部变量随着方法的调用而存在,随着方法的运行结束而消失
作用域不同
对象内存 在创建对象时系统最少会做七件事
加载class文件
申明局部变量
在堆内存中开辟一个空间
默认初始化
显示初始化
构造方法初始化
将堆内存中的地址值赋值给左边的局部变量
创建一个对象 范例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 //javabean类 //Student.java 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; } }
1 2 3 4 5 6 7 //测试类 //StudentTest.java public class StudentTest{ public static void main(String[] args){ Student student=new Student(); } }
字节码文件 :.java源文件经过编译生成的.class便是字节码文件,但还不能被系统直接执行,通过JVM解释翻译后才可以被底层系统执行。
首先StudentTest.java的字节码文件 加载到方法区,main方法在方法区临时存储。随后,虚拟机自动调用程序的主入口main方法,main方法会被压入栈内,然后利用代码 Student student=new Student(“zhangsan”,16);创建对象student,执行上述的七步,具体为:
加载class文件:
将Student.java加载到方法区,包括其中所有成员变量和方法
申明局部变量
Student student=new Student();执行“=”左边的代码,在栈内存的main方法中创建变量student,student能够存储Student类对象的地址值
在堆内存中开辟一个空间
Student student=new Student();执行“=”右边的代码。会将所有类中的成员变量和成员方法的地址值存储到堆内存
默认初始化
显示初始化
若在定义成员变量时直接赋值(比如priavte String name=”zhangsan”;private int age=15;)这就叫做显示初始化,不过范例中并未初始化,所以这步可忽略
构造方法初始化
范例中是空参构造,可以忽略;若是有参构造创建对象,name和age便会被赋值
将堆内存中的地址值赋值给左边的局部变量
Student student=new Student();将右边代码在堆中创建的对象的地址赋给student
注 :当main方法执行完毕,便会出栈,出栈后main方法的所有变量都会被释放,其中包括存储对象地址的变量,即范例中student变量被释放,若没有变量指向对象在堆内存中所处的空间,该空间便会消失。
多个对象 范例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 //javabean类 //Student.java 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; } }
1 2 3 4 5 6 7 8 //测试类 //StudentTest.java public class StudentTest{ public static void main(String[] args){ Student student1=new Student(); Student student2=new Student(); } }
student1创建步骤与上面创建单个对象的步骤大致相同。 student2不需要再次加载class文件,相对于student少了一步,而其他步骤与创建student1大致相同
多个引用指向同一对象 范例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 //javabean类 //Student.java 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; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 //测试类 //StudentTest.java public class StudentTest{ public static void main(String[] args){ Student student1=new Student(); Student student2=student1; student1.setName("ljs"); student1.setAge(15); System.out.println(student1.getName()); System.out.println(student2.getName()); System.out.println(student1.getAge()); System.out.println(student2.getAge()); student2.setName("sjl"); student2.setAge(16); System.out.println("=============="); System.out.println(student1.getName()); System.out.println(student2.getName()); System.out.println(student1.getAge()); System.out.println(student2.getAge()); } } /* ljs ljs 15 15 ============== sjl sjl 16 16 */
创建student1对象的步骤与创建单个对象的步骤大致相同,student2被赋值了student1存储的对象地址,student1和student2的存储的对象地址相同,也就是这两个变量指向同一个对象的地址,所以当其中一个对象的成员变量被改变,另一个也会跟着改变,比如student1.name改为sjl,student1.age被改为16,则student2.name和student2.age也会发生改变,变为sjl和16。 当student1和student2都不再存储对象在堆内存中所处的地址时,该对象会消失。