大家好呀,初识Java时,类与对象是我们遇到的第一个与c语言分歧比较大的点,因为之前的知识与c语言大差不差,本篇文章旨在帮助大家了解清楚类与对象的知识点,帮助初学者弄懂一些基本的知识与概念(笔者刚学时就傻傻分不清实例方法,静态方法,构造方法是什么,然后篇文章不涉及继承之后的知识点),希望对大家有所帮助,喜欢可以帮笔者点一个小小的赞,谢谢啦。
一 类的定义
类是同一类事物的统称,将现实世界的一个事物抽象成对象,类就是这类事物的统称,如鸟类,人类,家禽类。类用class关键字创建,在我们刚学Java用记事本写“hello world”时,就有一个class关键字
在写的时候我们知道这个文件的名字必须与类名相同(即class后面的名称)编译后生成class文件(这个class文件是二进制文件)后,就能在我们java虚拟机上运行。
当然,我们后续肯定是要用类似Idea这种集成开发环境编写代码,我们在定义类时,需注意以下几点
1.一个Java文件里可以定义多个类,但只能有一个public类
2.java文件文件名必须与public类的名称相同,如下图
我们在想定义一个public类时,编译器会报错,同样,当类名与文件名不一样时,编译器也会直接报错,当然,在这个类里我们就可以定义一些类的属性。
例如,我们在刚刚的文件定义一个Person类,每个人都有年龄,姓名,和身份证号
二 对象的创建(实例化)
有了一个类,实际上只是定义了一种属性,要想具体到具体的对象,就需要我们创建,在java中,使用new关键字创建一个对象,首先我们声明他,再创建他即通过new关键字为他分配内存,然后我们通过.操作符可以设置它的属性
三 类的构造方法
每个类都必须有构造方法,这个构造方法必须有,如果你不写的话,默认有一个无参的构造方法,java规定,类的构造方法名称必须与类名相同,没有返回值类型(void)也不允许有如下
public class Test{
Test(){}//构造方法
}
等价于
public class Test{
}
构造方法可以带参数,但是如果你自己写了一个构造方法,那么默认的构造方法便不再有了。一个类可以有多个构造方法构成重载,也可以用来初始化成员变量
1.4 类的实例变量与实例方法
类的每个变量或者方法都是一个实例,实例方法和变量是依赖于对象的,想要访问一个类中的实例变量或者方法,必须实例化出一个对象。(建议和静态变量于方法一起理解),例子和静态方法放在一起啦。
1.5 this引用
1 this在一个类中指向调用该方法或者变量的对象
public class Test {
String name;
Test(String name){
this.name=name;
}
public void eat()
{
System.out.println(this.name+"正在吃饭");
}
public static void main(String[] args) {
Test test=new Test("张三");
test.eat();
}
}
2 指向被局部变量隐藏的变量
public class Test {
int a=20;
public void test(){
int a=10;//局部变量和上面实例变量重名的情况,我们想要在方法里访问上面的a,就必须借助于关键字this
System.out.println(a);
System.out.println(this.a);//访问被隐藏的a
}
public static void main(String[] args) {
Test t=new Test();
t.test();
}
}
输出结果
3 this也可以在构造方法中调用该类的另一个构造方法,例如
public class Test {
public Test(){}
public Test(int a){
this();//调用该类中无参的构造方法
}
}
另外,这句调用的代码必须在该构造方法的第一行,否则会编译报错。
this引用的特性
1. this的类型:对应类类型引用,即哪个对象调用就是哪个对象的引用类型
2. this只能在"成员方法"中使用
3. 在"成员方法"中,this只能引用当前对象,不能再引用其他对象
4. this是“成员方法”第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法 对象的引用传递给该成员方法,this负责来接收
1.6 类的静态变量与静态方法
如果类的方法或变量被关键字static修饰,那他就是一个静态的方法或者变量,静态方法或者变量不依赖于对象,能通过类名调用,也可以通过对象(更推荐通过类名调用),在java代码序列化过程中,静态方法和变量便被加载到jvm中,因此,类的静态方法总是最先执行。
值得注意,静态方法中不允许this引用,因为this引用是依赖对象的,编译器会直接报错
public class Test {
int a;//实例变量
static int b;//静态变量
public void show1(){
System.out.println("实例方法被执行了");//实例方法
}
public static void show2(){
//int c=this.a;//报错
System.out.println("静态方法被执行了");//静态方法
}
public static void main(String[] args) {
Test test=new Test();
test.show1();//实例方法只能通过对象访问
Test.show2();//静态方法类名调用
}
}
此外,静态方法是类的特性,是所有依赖该类对象的共性
而实例方法依赖具体的对象
1.7 内部类
内部类是定义在类内部的类,大致分为以下几种
1 实例内部类
即未被static修饰的成员内部类
public class OutClass {
private int a;
static int b;
int c;
public void methodA(){
a = 10;
System.out.println(a);
}
public static void methodB(){
System.out.println(b);
}
// 实例内部类:未被static修饰
class InnerClass{
int c;
public void methodInner(){
// 在实例内部类中可以直接访问外部类中:任意访问限定符修饰的成员
a = 100;
b =200;
methodA();
methodB();
// 如果外部类和实例内部类中具有相同名称成员时,优先访问的是内部类自己的
c = 300;
System.out.println(c);
// 如果要访问外部类同名成员时候,必须:外部类名称.this.同名成员名字
OutClass.this.c = 400;
System.out.println(OutClass.this.c);
}
}
public static void main(String[] args) {
// 外部类:对象创建 以及 成员访问
OutClass outClass = new OutClass();
System.out.println(outClass.a);
System.out.println(OutClass.b);
System.out.println(outClass.c);
outClass.methodA();
outClass.methodB();
System.out.println("=============实例内部类的访问=============");
// 要访问实例内部类中成员,必须要创建实例内部类的对象
// 而普通内部类定义与外部类成员定义位置相同,因此创建实例内部类对象时必须借助外部类
// 创建实例内部类对象
OutClass.InnerClass innerClass1 = new OutClass().new InnerClass();
// 上述语法比较怪异,也可以先将外部类对象先创建出来,然后再创建实例内部类对象
OutClass.InnerClass innerClass2 = outClass.new InnerClass();
innerClass2.methodInner();
}
}
注意事项
1. 外部类中的任何成员都可以在实例内部类方法中直接访问
2. 实例内部类所处的位置与外部类成员位置相同,因此也受public、private等访问限定符的约束
3. 在实例内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,必须:外部类名 称.this.同名成员 来访问
4. 实例内部类对象必须在先有外部类对象前提下才能创建
5. 实例内部类的非静态方法中包含了一个指向外部类对象的引用
6. 外部类中,不能直接访问实例内部类中的成员,如果要访问必须先要创建内部类的对象。
2 静态内部类
被static修饰的内部成员类称为静态内部类
public class OutClass {
private int a;
static int b;
public void methodA(){
a = 10;
System.out.println(a);
}
public static void methodB(){
System.out.println(b);
}
// 静态内部类:被static修饰的成员内部类
static class InnerClass{
public void methodInner(){
// 在内部类中只能访问外部类的静态成员
// a = 100; // 编译失败,因为a不是类成员变量
b =200;
// methodA(); // 编译失败,因为methodB()不是类成员方法
methodB();
}
}
public static void main(String[] args) {
// 静态内部类对象创建 & 成员访问
OutClass.InnerClass innerClass = new OutClass.InnerClass();
innerClass.methodInner();
}
}
【注意事项】
1. 在静态内部类中只能访问外部类中的静态成员
2. 创建静态内部类对象时,不需要先创建外部类对象
3局部内部类
定义在外部类的方法体或者{}中,该种内部类只能在其定义的位置使用,一般使用的非常少
public class OutClass {
int a = 10;
public void method(){
int b = 10;
// 局部内部类:定义在方法体内部
// 不能被public、static等访问限定符修饰
class InnerClass{
public void methodInnerClass(){
System.out.println(a);
System.out.println(b);
}
}
// 只能在该方法体内部使用,其他位置都不能用
InnerClass innerClass = new InnerClass();
innerClass.methodInnerClass();
}
public static void main(String[] args) {
// OutClass.InnerClass innerClass = null; 编译失败
}
}
【注意事项】 1. 局部内部类只能在所定义的方法体内部使用
2. 不能被public、static等修饰符修饰
3. 编译器也有自己独立的字节码文件,命名格式:外部类名字$数字内部类名字.class
4. 几乎不会使用
4 匿名内部类
这部分内容和抽象类和接口紧密相关,后续在深入介绍
类与对象知识点到这里啦,谢谢大家。