什么是面向对象?什么是面向过程?⏰
一件事可能会细化成很多小事,如果是每件小事都要自己去编代码实现,才能够完成整件事,我们可以称之为面向过程。
一件大事可以分为简单的几个模块,通过这几个简单模块的交互(可以理解为合作)就可以完成整件事,此时可以称为面向对象
针对面向对象要干三件事
对象从何而来?
从类而来。类由关键字class修饰,类名统一使用大驼峰。
一个类里包含哪些东西?
class Person{
public String name;
public int age;
public void eat(){
System.out.println(name+"正在吃饭");
}
}
有了类如何产生对象?
由类产生对象的过程叫做实例化,如:Person per=new Person();
须知:由类产生对象的过程,类在此处扮演一种类型的角色,就像int a=10;中的int 那样,并且有类定义的变量为引用变量,故:per是一个引用变量。new为关键字,在堆中实例化了一个对象。当然per也可以像指针那样不指向任何的对象,即:Person per=null;
有了对象,如何去访问对象的成员?
首先由类产生对象,类此时相当于一个“模板”,照着这个模板可以造出很多对象,针对对象成员的访问,要通过该对象的引用加一个**.**来访问。
如果定义类时,并没有对其成员进行初始化,那么在主函数中打印由该类实例化的对象的成员时,结果是什么?
基本数据类型 | 整型(byte/short/int/long)=0;浮点型(float/double)=0.0;字符型(char)=\u0000;布尔类型(boolean)=false |
---|---|
引用数据类型 | 字符串\数组\枚举\接口=null |
变量是否被static修饰,有什么区别?
类中的成员(字段或者方法)被static修饰后,那这个成员将和类的代码片段一起存进方法区,不和该对象的普通成员变量一起存在堆中,并不意味着对象就不能用(访问)这个静态成员变量(类变量)了哈!可以用,只不过对静态成员变量的修改是永久性的,上代码:
class Person{
public String name;
public int a;
public static int age;
public void eat(){
System.out.println(name+"正在吃饭");
}
}
public class Main{
public static void main(String [] args){
Person per1=new Person();
per1.a++;
per1.age++;
System.out.println(per1.a);
System.out.println(Person.age);//类变量,用类名作成员访问
System.out.println("============");
Person per2=new Person();
per2.a++;
per2.age++;
System.out.println(per2.a);
System.out.println(Person.age);//类变量,用类名作成员访问
}
}
//打印结果:
//1
//1
//=========
//1
//2
针对存在static修饰类的成员的情况,有几个注意事项
针对一个类实例化的对象所对应的引用变量来说,有几个注意点
class Person{
public String name;
public int age;
public static count;
public void eat(){
Syetem.out.println(name+"正在吃饭");
}
}
public class Main{
Person per=new Person();
public static void main(String [] args){
Main main=new Main();
}
}
//引用变量main在栈上,指向堆中的对象,该对象上来就是一个引用变量per,这个per又在堆新new了一个对象,此时就构成了引用不再堆上的情况。
5.一个对象存储到哪里,和它是否被final修饰没关系,final类似C中的const,只不过赋予一个变量常属性。存到哪里还是要看是不是static修饰。
重写
我们常看到一个类实例化对象后,用sout对该对象的引用进行打印,其结果通常为引用所对应的类名再加一个@再加一个哈希值(暂时理解为经过处理的地址),为什么会这样,剖析源代码可以看出,sout打印出的东西,其实受一个函数String toString()的控制,只要在类中定义一个开放权限的(public)的toString(),我们就可以使sout一个引用打印出任何我们想打印的结果。
这里有一个快捷键:Alt+insert生成toString()即可。
封装
1.前面的代码中public一直未做解释,其实public是一个访问权限控制符,对应还有private或者什么都不写,这里先只介绍public和private。
2.public:“公开”,对谁公开?对类的调用者来说公开,也就是被public修饰了的成员,可以直接被类的调用者去通过引用去使用。
3.private:“私人的”,也就是不公开,类的调用者不可以直接使用private的东西。或者换句话说,被private修饰的成员,只能在所在类内使用。
4.存在的意义?
类的定义者改动代码,会使得类的调用者废很大劲改成一样的,否则代码错误。封装起来,只有定义者考虑代码的改动,封装了都会提供接口供调用者去使用(修改成员变量等),那你又会说,接口再被定义者改来改去咋办?一般不会这样♂
针对封装的接口
getter和setter
上代码:
class Person{
private String name;
private int age;
public void setname(String name){
this.name=name;//this表示当前对象的引用
}
public void getname(){
return name;
}
}
public class Main{
public static void main(String[] args){
Person per=new Person();
per.setname("java");
String name=per.getname;
System.out.println(name);
}
}
那会有个问题,若一个类中有很多被private修饰的字段,定义者总不能针对每个字段都逐一去码代码提供接口吧?
这里就有快捷键:Alt+insert,或者右键→Getter and Setter→选择需要设置的字段接口就可以了。
构造方法
概念:方法名与类名一致,无返回值
构造方法干嘛的?
对象的实例化必不可少的一步。
因为一个对象的产生需要两步:
new进行对象实例化的时候其实已经在调用构造方法了new Person();
构造方法即使我们不去定义它,编译器也会自动生成不带参数,也没有内容的构造方法,所以说一个对象的产生,必要有一步:调用合适的构造方法,我们没定义,它也要造一个去调用。
多个构造方法其实构成了方法的重载,那实例化对象的时候调用的到底是哪个构造方法(因为它们的名字都是一样的,都是类名),这要根据你new Person(参数),这里的参数情况,去调用参数情况一致的那个构造方法。
代码块☢️
字段的初始化:
注意事项:
匿名对象