文章目录
1、学习类和对象前需了解的知识
面向过程:注重的是过程,在整个过程中所涉及的行为,就是功能。
面向对象:注重的是对象,也就是参与过程中所涉及到的主体。是通过逻辑将一个个功能实现连接起来。
Java是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。
举例说面面向对象和面向过程:洗衣服
面向过程:①将衣服泡在盆里;②手动搓洗衣服;③拧干衣服;④将衣服晾干
面向对象:①将衣服放在洗衣机里启动并等待;②晾干衣服
在上述的例子中,洗衣机就相当于对象。
面向对象的概念:
①面向对象是思考问题的一种思考方式,是一种思想。
②类就是一类对象的统称。对象就是这一类具体化的实例。
③面向对象的好处:将复杂的事情变得简单,只要面对一个对象即可。
总之面向对象就是用代码(类)来描述客观世界的事物的一种方式。一个类主要包含一个事物的属性和行为。
2、类和类实例化
2.1 类的创建和使用
声明一个类就是创建一个新的数据类型,而类在Java中属于引用类型,Java使用关键字class来声明类。基本语法如下:
//创建类
class <class_name>{
field; //成员属性
method; //成员方法
}
//实例化对象
<class_name> <对象名> = new <class_name>();
说明:
① class为定义类的关键字,ClassName为类的名字,{}中为类的主体。
② 类中的元素称为:成员属性。类中的方法称为:成员方法
示例:创建一个学生类
public class Test {
public static void main(String[] args) {
Student stu1 = new Student();//实例化对象,使用new关键在堆内存中开辟对象的空间
stu1.name = "张三";
stu1.age = 18;
stu1.sex = '男';
stu1.study();
//可以使用该类创建多个对象
Student stu2 = new Student();
Student stu3 = new Student();
}
}
new关键字执行过程:首相为对象分配内存空间,然后调用对象合适的构造方法。
此时创建了学生类,但是该如何使用这个类呢?使用类创建对象的过程就称为类的实例化。实例化出的对象占用实际的物理空间,存储类成员变量。
示例:使用Student类创建对象
public class Test {
public static void main(String[] args) {
Student stu1 = new Student();//实例化对象,使用new关键在堆内存中开辟对象的空间
//使用对象名.属性来访问类中的属性,使用对象名.方法调用类中的方法
stu1.name = "张三";
stu1.age = 18;
stu1.sex = '男';
stu1.study();
//可以使用该类创建多个对象
Student stu2 = new Student();
Student stu3 = new Student();
}
}
输出结果:
好好学习,天天向上
2.2 认识null
null在Java中为“空引用“,表示不引用任何对象,如果对null进行访问操作(对象名 . 属性或者对象名 . 方法)就会引发异常。
public class Test1 {
public static void main(String[] args) {
Student stu = null;
stu.name = "李四";
}
}
运行结果:
Exception in thread “main” java.lang.NullPointerException
at Test1.main(Test1.java:4)
说明:空指针异常( java.lang.NullPointerException)的引发原因就是对null进行了访问操作。
2.3 成员属性初始化
在Student类中,并没有给成员属性初始化,因此默认值分别为:null、0、’\u0000’,但是如果在写代码的时候也可以设置初始化值。如下:
public class Student {
public String name = "李四";
public int age = 20;
public char sex = '男';
}
2.4 方法
普通方法:可以用来描述对象的行为。例如:
public class Student {
public void study(){
System.out.println("好好学习,天天向上");
}
public void sport(){
System.out.println("锻炼身体");
}
public void sleep(){
System.out.println("睡觉");
}
}
该类中的方法描述学生的行为,例如对象调用sport()方法,则表示学生此时行为”锻炼身体“。
构造方法:是方法中的特殊方法。在实例化对象的时候会被自动调用到的方法,方法名字和类名相同,用于对象的初始化。
构造方法的使用规则:
① 方法名称必须与类名称相同
② 构造方法中没有返回值类型声明
③ 每个类中必须至少存在一个构造方法。(如果没有定义,则系统自动生成无参构造方法)
如下:
public class Student {
public String name;
public int age;
public char sex;
public Student(){}//无参构造方法
public Student(String name,int age){//两参构造方法
this.name = name;
this.age = age;
}
public Student(String name, int age, char sex) {//三参构造方法
this.name = name;
this.age = age;
this.sex = sex;
}
}
说明:
① 构造方法可以有多个,也可以有一个,也可以没有。如果类中提供了构造方法,则系统不再自动生成。
② this关键字表示当前对象的引用。上述代码这样做是为了区别方法中的变量和类中的属性(建议类中的属性都加上this关键字)。
③ 构造方法支持重载,规则和普通方法的重载一致。
2.5 static关键字
static关键字可以修饰属性、方法、代码块、类。使用static关键字修饰之后不依赖于具体的对象实例。
修饰属性:Java静态属性和类相关,与具体实例无关。
class Demo{
public int a;
public static int count;
}
public class Test {
public static void main(String[] args) {
Demo demo = new Demo();
demo.a++;
System.out.println(demo.a);
Demo.count++;
System.out.println(Demo.count);
}
}
注意:使用static关键字之后是所有的对象共享,因此调用的时候直接使用类名.属性调用即可。且使用static修饰后存储的位置不是在堆上的对象内存中,而是处于方法区中。
输出结果:
1
1
修饰方法:使用static修饰之后的方法称为静态方法。静态方法属于类,而不是属于类的对象。
说明:
① 静态方法中只能调用静态方法,非静态方法既可以调用静态方法也可以调用非静态方法。
② 静态方法中只能操作静态属性,非静态方法中既可以操作静态属性也可以操作非静态属性。
class MyMath{
public int a;
public static int count ;
public final int SIZE = 10;
public static void change(){
count = 10;
}
public void add(){
count++;
a++;
}
}
public class Test {
public static void main(String[] args) {
MyMath.change();
System.out.println(MyMath.count);
MyMath math = new MyMath();
math.add();
System.out.println(math.a);
System.out.println("final修饰常量:" + math.SIZE);
}
}
输出结果:
10
1
final修饰常量:10
说明:final修饰常量,且规定使用大写字母表示。被final修饰之后的常量在后续的代码中只能使用而不能做修改。
2.6 this关键字
this表示当前对象引用,可以借助this来访问对象的成员属性和方法。
访问属性:可直接在类中使用this.属性调用类中的属性,使用this为了防止和方法中的变量重名而产生歧义。
public class Student {
public String name;
public int age;
public String toString(){
return "姓名:" + this.name + "、年龄:" + this.age;
}
}
在该代码中toString()方法使用this关键字访问属性。toString()方法原本功能是返回在堆内存中的地址,但是经过重写之后可返回自己想要的结果。
调用方法:使用this.方法名()调用本类中要使用的方法
public class Student {
public String name;
public int age;
public char sex;
public void study(){
System.out.println("好好学习,天天向上");
this.sport();
}
public void sport(){
System.out.println("锻炼身体");
this.sleep();
}
public void sleep(){
System.out.println("睡觉");
}
}
public class Test {
public static void main(String[] args) {
Student stu = new Student();
stu.study();
}
}
输出结果:
好好学习,天天向上
锻炼身体
睡觉
在Student类中的study()方法调用了sport()方法,然后在sport()方法中调用了sleep()方法。
构造方法互调用:构造方法互调用只能发生在构造方法之间,但是构造方法也可以调用普通方法。
public class Student {
public String name;
public int age;
public char sex;
public Student(){//无参构造方法
this("张三",20,'男');//构造方法互调用
}
public Student(String name,int age){//两参构造方法
this(name,age,'男');
this.sleep();
}
public Student(String name, int age, char sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
}
注意:
① 使用构造方法互调用的时候只能放在方法中的第一行。并且必须设置有出口。
② 静态方法的内部不能使用this关键字。
3、代码块
使用{ }定义的一段代码。代码块分为四种:普通代码块、构造代码块、静态代码块和同步代码块。
3.1 普通代码块
public class Test_4 {
public static void main(String[] args) {
{//直接使用{}定义,普通代码块
int x = 10;
System.out.println("x1 = " + x);
}
int x = 20;
System.out.println("x2 = " + x);
}
}
结果:
x1 = 10
x2 = 20
3.2 构造代码块
构造代码块定义在类中(不加修饰符)。一般用于初始化实力成员变量。
class Person{
public String name;
public int age;
public Person(){
System.out.println("调用了构造方法");
}
{//构造块
this.name = "张三";
this.age = 18;
System.out.println("构造块的使用");
}
public String toString(){
return "姓名:" + this.name + "、年龄:" + this.age;
}
}
public class Test {
public static void main(String[] args) {
Person per = new Person();
System.out.println(per);
}
}
输出结果:
构造块的使用
调用了构造方法
姓名:张三、年龄:18
说明:构造块先与构造方法执行。构造方法可以执行多次。
3.3 静态代码块
使用static定义的代码块。一般用于初始化静态成员属性。
class Person{
public String name;
public int age;
public static int count;
public Person(){
System.out.println("调用了构造方法");
}
static{//静态代码块
count = 10;
System.out.println("使用了静态代码块");
}
public Person(String name,int age){
this.name = name;
this.age = age;
}
static {//静态代码块
count /= 5;
}
{
this.name = "张三";
this.age = 18;
System.out.println("构造块的使用");
}
public String toString(){
return "姓名:" + this.name + "、年龄:" + this.age;
}
}
public class Test_4 {
static {//静态代码块
System.out.println("主类中的静态代码块");
}
public static void main(String[] args) {
Person per1 = new Person();
System.out.println(per1);
System.out.println(Person.count);
System.out.println("==================分割线=================");
Person per2 = new Person();
System.out.println(per2);
System.out.println(Person.count);
}
}
输出结果:
主类中的静态代码块
使用了静态代码块
构造块的使用
调用了构造方法
姓名:张三、年龄:18
2
==================分割线=================
构造块的使用
调用了构造方法
姓名:张三、年龄:18
2
说明:
① 静态代码块若是在主类中,则先与主方法执行。
② 若是类中既有静态块,又有构造块,则静态块先与构造块执行。
③ 如果类中有多次使用static修饰,则按照代码的顺序来依次执行static修饰的方法或者静态代码块。
④ 类中的静态代码块只执行一次。
4、封装
封装的本质就是让类的调用者不必太多的了解的实现者是如何实现类的,只要知道如何使用类就行了,这样就降低了类使用者的学习和使用成本,从而降低了复杂度。
4.1 private实现封装
private/public这两个关键字表示“访问权限控制”。
· 使用public修饰的成员变量或者成员方法,可以直接被类的调用者使用。
· 使用private修饰的成员变量或者成员方法,不能被类的调用者使用(类外无法访问)。
class Book{
private String title;//使用private封装,类外部无法访问,只能提供getter方法和setter方法
private double price;//使用private封装,类外部无法访问,只能提供getter方法和setter方法
public Book(){}//无参构造方法
public Book(String title,double price){
this.title = title;
this.price = price;
}
//setter方法
public void setTitle(String title) {
this.title = title;
}
public void setPrice(double price) {
this.price = price;
}
//getter方法
public String getTitle() {
return title;
}
public double getPrice() {
return price;
}
//toString()方法
public String toString(){
return "图书名称:" + this.title + "、图书价格:" + this.price;
}
}
public class Test {
public static void main(String[] args) {
Book bookA = new Book();//使用无参构造
bookA.setTitle("Java入门");//使用setter方法设置属性值
bookA.setPrice(22.5);//使用setter方法设置属性值
System.out.println(bookA.toString());
System.out.println("==================分割线===================");
Book bookB = new Book("Spring入门",28.6);//使用两个参数的构造方法
System.out.print("书名:" + bookB.getTitle());//使用getter方法获取属性值
System.out.print("、价格:" + bookB.getPrice());//使用getter方法获取属性值
}
}
输出结果:
图书名称:Java入门、图书价格:22.5
==================分割线===================
书名:Spring入门、价格:28.6
解析:
① 属性使用了private进行封装,外部无法进行访问修改获取属性值。
② 由于属性被封装,因此需要提供setter、getter方法,使外部类借助setter方法设置属性值,借助getter方法获取属性值。如果不提供setter、getter方法在类外部访问时会出现编译错误。
③ 重写父类(Object)中的toString()方法,使得返回值是自己想要的结果。
5、匿名对象
匿名对象只是表示没有名字的对象。没有引用的对象成为匿名对象;匿名对象只能在创建对象时使用;如果一个对象只是用一次,后面就不在使用,那么可以考虑使用匿名对象。
代码实例:匿名对象的使用
//Book类为封装中的示例
public class Test_5 {
public static void main(String[] args) {
System.out.println(new Book("线性代数",20.1).toString());
}
}
输出结果:
图书名称:线性代数、图书价格:20.1