粗缯大布裹生涯,腹有诗书气自华
作者:Mylvzi
文章主要内容:Java学习之--类和对象
利用类创建一个具体的对象就叫做类的实例化!
当我们创建了一个类,实际上就是创建了一个“自定义类型”(和C语言中的结构体类似),是一种新的类型。既然是类型,就和Int,char一样可以进行变量的创建。创建的变量是一种引用变量,变量内部存储的是创建对象的地址!
1.类类似于结构体,是一种自定义类型,通过.操作符访问成员变量
2.类可以创建多个对象,比如此处还可以创建stu2,stu3.......
3.类:理解为图纸,不占用物理地址;但是通过图纸创建出房子的时候,房子(对象)占用物理地址。
先来看两个问题:
// 创建一个学生类
class Stu{
public String name;
public String sex;
public int age;
// 所有对成员变量进行操作的地方都要添加this,代表是当前对象调用的方法!!!
// this写在方法内部
public void setStu(String name,String sex,int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
public void printStu() {
System.out.println(this.name+" "+this.sex+" "+this.age);
}
}
public class Test2 {
public static void main(String[] args) {
// 实例化一个stu1的对象
Stu stu1 = new Stu();
Stu stu2 = new Stu();
Stu stu3 = new Stu();
stu1.setStu("lvzi","nv",18);
stu2.setStu("biandu","nan",19);
stu3.setStu("栀子","nv",20);
stu1.printStu();
stu2.printStu();
stu3.printStu();
}
}
this引用的作用就是告诉编译器我当前我调用的是哪个对象,对当前对象的成员变量进行操作!!!避免了很多可能出现的错误
1.this只能在成员方法内部使用。
2.this只能调用当前对象,不能再调用另一个对象
3.实际上,成员方法内部其实是有“对象”这个参数的,只不过一般被省略!!!
4.this是Java中的一个关键字,表示对象的引用
可是如果每次都需要调用方法来初始化对象是否过于麻烦?有没有其他方法可以初始化对象呢?答案是可以的,接下来就讲解初始化对象的一种特殊方法-->构造方法!!!
是一种用来初始化对象的特殊方法
1.不需要写返回值
2.只负责初始化对象,并不负责给对象开辟空间
3.方法名必须和类名相同!!!
4.创建完对象,编译器会自动进入到构造方法内部(代码演示)
// 带参数的构造方法
public Stu(String name,String sex,int age) {
this.name = name;
this.sex= sex;
this.age = age;
}
// 利用带参数构造方法,只需在创建对象时传入参数即可
// 编译器会进入到构造方法,帮助你初始化成员对象
Stu stu1 = new Stu("绿子","女",18);
stu1.printStu();
1.this必须写在第一行!!!不是第一行就无法通过编译
2.不能呈环!!!
3.绝大多数情况下构造方法使用public来修饰,特殊情况下使用private修饰
4.this是一种引用,哪个对象调用,就引用哪个对象,this此时就是一种引用数据类型,存储的是指向对象的地址!!!
总结:所谓的构造方法就是一种用来初始化对象的特殊方法!!!方法名必须和类名相同,通过带参数的构造方法可以快速进行对象的初始化!!!
上文已经提到过,成员变量不初始化也可以以通过编译,并有默认值,主要是因为编译器提供了一个默认的构造方法,在对象创建时就会被调用。实际上,通过new关键字来实例化对象要做的工作很多!
// 就地初始化(写死了)
public String name = "绿子";
public String sex = "girl";
public int age = 18;
我们见到的电脑主机往往都被一层黑壳包住,我们只需要通过主机上的接口来实现和计算机之间的交互。但实际上,主机内部有着复杂的电子元件,来实现特定的功能!但我们并不关心他内部的属性,以及如何运转的,我们只需要通过接口来实现交互,这种将属性和内部方法(实现细节)隐藏的做法就是封装!
在计算机中,通过类来存储属性和方法!那如何实现封装呢?通过访问修饰限定符来实现!
public:公开,可跨包,跨类
protected: 不能跨包
default:默认权限,不可跨包
private:只能在同一包同一类使用
public class Stu2 {
// 访问修饰限定符
private int age;
String sex;
public String name;
public Stu2(int age,String sex,String name) {
this.age = age;
this.name = name;
this.sex = sex;
}
public void stuRun() {
System.out.println(this.name+"i am running!");
}
public void stuSleep() {
System.out.println(this.name + "i am sleeping!");
}
public static void main2(String[] args) {
Stu2 stu = new Stu2(14,"男","边度");
System.out.println(stu.age);// private 只能在Stu2类中访问
System.out.println(stu.sex);// default 默认权限,可以在当前包中任意类访问
System.out.println(stu.name);// public 公开权限,可跨包访问
stu.stuRun();
stu.stuSleep();
}
}
private:无法跨类访问
一般情况下,成员变量设置为private,方法设置为public
那如果我想在类外使用private属性的成员变量该怎么办呢?答案是:使用set和get方法(方法被设置为公开的,无法访问成员变量,但可以访问方法,通过方法来访问成员变量)
上文提到default无法跨包访问,那什么是包呢?包就是类的集合,是用来管理类的!可以把包理解为一个大的文件夹,里面存放的是各种类,通过包可以很好的组织,管理类!比如当你不想当前包的类被其他包访问,就可以修饰为default;包还有一个重要的作用,在同一个工程内,可以出现两个相同名字的类,只要处于不同的包中。(在两个文件夹内都有“周杰伦歌曲”这个类,电脑也不会报错)
其实Java中提供了很多的现成的类供我们使用,比如常见的util类,Arrays类等等;在使用这些类时,要进行相应的导入,导入是通过import
如果需要使用 java.util 中的其他类, 可以使用 import java.util.*
import java.util.*;
import java.sql.*;
Date date = new Date();// err
// 如果存在访问冲突,要写具体,是哪个包中的类
java.util.Date date = new java.util.Date();
import static java.lang.Math.*;
public static void main(String[] args) {
double x= 2.0;
double y = 3.0;
System.out.println((Math.pow(x, 2) + Math.pow(y, 2)));// 13.0
// 添加static关键字,可以直接使用方法名,不需要再添加Math了,这样写更方便,但不建议用
System.out.println(pow(x, 2) + pow(y, 2));
}
注意:
import和C语言中的include不一样,include是导入文件,import是导入相应的类,使用相应的方法!!!同时,include包括所有函数的具体实现方法,Import只是导入接口的声明,并不包括具体的实现细节;include加头文件是在预处理阶段就进行的,而import是在编译阶段进行
常见的包:
1. java.lang:系统常用基础类(String、Object),此包从JDK1.1后自动导入。
2. java.lang.reflect:java 反射编程包;
3. java.net:进行网络编程开发包。
4. java.sql:进行数据库开发的支持包。
5. java.util:是java提供的工具程序包。(集合类等) 非常重要
6. java.io:I/O编程开发包。
在编译器中快速查看常见包:双击shift
所有对象共享的成员变量就叫做静态成员变量!通过static关键字修饰。静态成员变量不属于对象,而是属于类!推荐通过类来访问静态成员变量!
class Stu{
// 实例成员变量-->每个对象都包含一份
int age;
String name;
String sex;
// 假如三位学生都是一个班的,现在要创建一个classroom的成员变量
// 由于他们都是一个班的,可以说他们共享一个“classroom”
// 共享的成员变量就是静态成员变量
public static String classroom = "110";
public Stu(int age, String name, String sex) {
this.age = age;
this.name = name;
this.sex = sex;
}
}
public class Test {
public static void main(String[] args) {
Stu stu1 = new Stu(15,"biandu","boy");
Stu stu2 = new Stu(18,"绿子","girl");
Stu stu3 = new Stu(19,"栀子","boy");
// 直接通过类名访问(推荐)
System.out.println(Stu.classroom);
// 通过对象访问(不推荐)
System.out.println(stu1.classroom);
System.out.println(stu2.classroom);
System.out.println(stu3.classroom);
}
注意:
1.静态方法内部不能出现this引用,因为this引用必须指明对象,静态方法不属于对象,静态方法是类的方法!
2.不能在静态方法内部访问任何非静态成员变量!
3.在静态方法内部不能直接引用非静态方法(因为非静态方法内部都有this的引用)但可以在非静态方法内部创建一个对象,通过对象来访问非静态方法!
被{}围起来的代码就叫做代码块!
分类:
普通代码块
构造块
静态块
同步代码块(后续讲解多线程部分再谈)
定义在方法内部的代码
public static void main(String[] args) {
// 普通代码块
{
int x= 10;
System.out.println(x);// 输出10
}
System.out.println(x);// err x只能在上面的代码块内部使用
用来初始化实例变量的代码块
// 实例代码快-->用来初始化实例变量(不加修饰符)
{
this.age = 12;
this.sex = "女";
this.name = "绿子";
}
Stu stu1 = new Stu();
System.out.println(stu1.name);// 输出绿子
用来初始化静态变量!!!
public static String classroom;
static {
classroom = "222202";
System.out.println("hello world");
}
注意:
1.静态代码块多少个对象,代码块只会被执行一次(创建对象的时候执行唯一一次)
2.代码块的优先级高于构造方法
3.如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次执行(合并)
总结:实例代码块和静态代码块的区别
1.实例代码块只能在对象创建的时候才会被调用,而静态代码块不需要创建对象就可以直接通过类来访问
2.静态代码块只能被执行一次,而实例代码块可以被执行多次(实例化一个对象就执行一次)
1.封装是面向对象(Object Oriented program)的三大特征(封装,继承,多态),通过封装能更好的管理成员变量
2.类是面向对象重要的部分,通过将研究的事物分离出来各种类,通过类之间的交互来完成工作
3.类是对现实事物的抽象化处理,通过new关键字进行对象的实例化
4.构造方法是一种特殊的初始化成员变量的方法;掌握命名规则和如何快速创建
5.理解静态成员变量和实例变量的区别
6.代码块也是用来初始化成员变量的,其优先级很高
7.通过改写toString方法以字符串的形式打印成员变量