什么是类?什么是对象?
class 类名{
//属性 -> 字段 -> 成员变量
//方法 -> 成员方法
}
class Person{
public String name;
public int age;
public void eat(){
System.out.println(name+"正在吃饭!");
}
public void print(){
System.out.println("姓名:" + name + "年龄" + age);
}
}
所以一个类之间包含属性和方法。
由类产生对象的过程叫做实例化。
那么如何实例化对象呢?
用这个类型定义一个变量然后new一个对象出来。相当于这个引用指向了这个对象。
Person person = new Person();
person是一个变量,不过这个变量存储的是地址,所以这个变量也被叫做引用。
一个类可以实例化多个对象;
class Person{
public String name;
public int age;
public void eat(){
System.out.println(name + "正在吃饭");
}
public void print(){
System.out.println("姓名:"+ name + "年龄" + age);
}
}
public class TestDemo {
public static void main(String[] args) {
Person person = new Person();
System.out.println(person.name);
System.out.println(person.age);
person.eat();
person.print();
System.out.println("============");
Person person1 = new Person();
person1.name = "gaobo";
person1.age = 19;
System.out.println(person1.name);
System.out.println(person1.age);
}
}
类的成员
1.字段 -》属性-》成员;
成员分为:普通成员变量和静态成员变量(类名.静态成员的属性和方法)
以下代码输出1的原因在我上面画的图显示的很清楚,因为他们person和person2的地址不同,内存也不同,++不互相影响。
public class TestDemo {
public static void main(String[] args) {
Person person = new Person();
person.age = 1999;
System.out.println(person.age);//输出1
System.out.println("=================");
Person person2 = new Person();
person2.age++;
System.out.println(person2.age);//输出1
}
注意看静态成员变量的引用是有报错存在的。那么他会如何输出?
输出结果:
这是为什么?
原因在于:
静态成员变量有个新名字叫做类变量。
被static修饰的是被放在方法区的。
他之所以报警告是因为他不需要对象,只需要通过类名就可以访问。总之,静态的是类的不需要对象。
并且静态的东西只在方法区存储一份,所以结果就是2。
方法区:
1.存储代码的片段
2.静态成员方法的访问:
不需要像普通成员变量的new对象。
3.能不能在普通方法的里面写静态的成员变量吗?
答案:不可以
原因:
1.static定义的变量,类变量,是属于类的
2.eat方法的调用,需要对应的引用来调用。但是如果可以定义static的变量,通过Person就可以调用了,所以这两个再起来就发生冲突,一个想要new个对象,但是static不需要对象。
4.那么我们能不能把静态变量放在类方法里面?
答:也是不可以的,因为静态定义的是属于类的,而放到类方法里面之后就属于方法的了,是不能做到的。
5.能不能在普通方法里面调用静态方法?
答:可以,普通方法是依赖对象的,静态方法不依赖对象的。权限范围更大。
6.能不能在静态方法里面调用普通方法?
答:不可以,因为静态方法不需要对象,但是普通方法需要。
实在想定义可以在里面new一个对象就好,但是一般不常用。
写错了也没关系,编译器会提醒。
面试题:
为什么main函数是静态的?
这个是根据JVM来的,是不是静态都可以。
这个代表这个引用不指向任何对象
这个代表person2这个引用指向person这个引用多指向的对象,也就意味着他们指向的是同一个对象。
3.同时一个引用不可以同时指向多个对象,如果有多次,最后一次就是它的对象。
4.引用一定要在栈上吗?
答。不是,就比如我这样写代码。
static修饰
一个对象存储在哪里和你是否被final修饰没关系,被final修饰后不可再次更改。
重写打印
通过这三张图我们可以知道其实System.out.println(person);的输出就是通过public String toString() 一条代码来实现的就是:
并且我们还有快捷键去实现这个代码
Alt + insert并选择toString()即可实现;
结果:
封装
我们一般用private来实现封装
private 只能在当前类的当中使用它。封装可以使程序变得更安全。
age如果是这样设置,出现警告,这是因为局部变量优先,这段代码相当于自己给自己赋值,所以警告。
但是我们添加this就可以避免出现这个警告。
同时我们也可以用编译器自动生成get和set方法,alt+insert点击getter和setter就可以了。
构造方法
构造方法:方法和类名是相同的,且构造方法比较特殊,没有返回值。没有构造方法,我们是不能实例化对象的。
有什么用?-》一个对象的产生【对象的实例化】
1.为对象分配内存。
2.调用合适的构造方法。
合适的这个词代表构造方法不止一个
class Person{
//成员变量
private String name;
public int age;
public Person(){
System.out.println("Person()::不带参数的构造方法");
}
}
public class TestDemo {
public static void main(String[] args) {
Person person = new Person();
}
}
不能改成private,private只能在类里面使用,类外是不能实例化对象。但是在类内可以实例化对象。
结论:如果没有实现任何的构造方法,编译器会帮助我们,默认生成一个不带参数的构造方法,也就是说一个类,至少会有一个构造方法,就算你没有写。
如何调用带有一个参数的构造方法?
在实例化对象的时候传参就行。
总结2:如果当前类有其他的构造方法,那么,编译器就不会生成不带参数的构造方法的。
总结3:构造方法之间可以构成重载。
我们之前使用了this,那么this代表当前的对象?
错,调用完合适的构造方法之后才能产生实例化对象,this只能代表代表当前对象的引用。
this
在静态方法里面不能使用this
1.this.data 调用当前对象的属性(我们之前用的都是这种,就不解释了)
2.this.func() 调用当前对象的方法
3.this() 调用当前对象的其他方法,同时this在构造函数调用时,必须放在第一行。只能存放在构造方法中。
class Person{
//成员变量
private String name;
public int age;
public Person(){
this("nianian",19);//这代表调用一个参数的构造方法
System.out.println("Person()::不带参数的构造方法");
}
public Person(String name){
this.name = name;
System.out.println("Person(String)::带一个String类型参数的构造方法");
}
public Person(String name, int age){
this.name = name;
this.age = age;
System.out.println("Person(String,int)::带一个String类型和int类型参数的构造方法\"");
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
// }
}
public class TestDemo {
public static void main(String[] args) {
Person person = new Person();
System.out.println(person);
}
代码块
1.本地代码块 在psvm里面直接{}
2.实例代码块
3.静态代码块
代码块是怎么被调用的?
调用顺序
下面这张图中,可以发现尽管你new了两个对象但是静态代码块只被执行了一次,与new多少对象没关系。
同时,也不用实例化对象都可以执行。
如果都是静态的情况下赋值的话,最终的结果是和定义的顺序是有关系的。(建立在已经初始化的情况下)。
匿名对象
匿名对象与普通对象的对比。