目录
- 一、面向对象与面向过程
- 1.1 两者的概念
- 1.2 举例
- 二、类和对象的概念
- 2.1 概念
- 2.2 基本语法
- 2.3 举例
- 2.4 内存布局
- 2.5总结
- 三、static关键字
- 3.1 static修饰属性,类属性,类变量
- 3.2 static修饰方法,类方法,工具方法
- 3.3 static修饰代码块
- 3.3.1 普通代码块
- 3.3.2 成员代码块
- 3.3.3 静态代码块
- 四、面向对象的封装特性,暂时学过private
- 4.1 修饰符权限
- 举例
- 五、构造方法
- 5.1 构造方法的语法规则
- 5.2 举例
- 六、this关键字
- 七、匿名类
- 八、toString方法
一、面向对象与面向过程
1.1 两者的概念
通俗一点来说,面向过程就是用户是需要知道做一件事情的全过程。当解决一个问题的时候,我们将其拆封成多个步骤来进行。
面向对象:解决一个问题的时候,我将事物抽象成一个个对象,向对象里增添成员和方法。我们调用对象里的方法就可以解决问题。不需要关心这个问题是如何解决的,反正用了这个方法,就能解决这个问题。
1.2 举例
我要进行洗衣服这个操作!!!
面向过程:
- 执行放衣服的方法
- 执行放洗衣凝珠的方法
- 执行清洗的方法
- 执行烘干的方法
面向对象:- 创建洗衣机和人两个对象
- 洗衣机里有属性和方法(清洗方法和烘干方法)
- 人有属性和方法(放衣服方法和放洗衣凝珠方法)
- 最后,通过对象去调用这些方法达到洗衣服的目的
二、类和对象的概念
2.1 概念
类是一个抽象概念,我们把具有相同属性和行为的对象抽象成一个类。
对象是类的实例化,这些对象拥有类的属性和行为,即某个具体的实体,有个一个对象,这些属性才有值,这些行为才有了意义。
2.2 基本语法
//创建类
class <class_name> {
field; //成员属性
method; //成员方法
}
//创建一个对象
<class_name> <对象名> = new <class_name>();
2.3 举例
- 每个人都有名字,年龄,国籍,这些成为属性。
- 每个人都会吃和睡觉,这些成为行为。
- 我们可以创建人这个类
- 有个这个类我们就可以创建对象,用new关键字
- 通过对象去调用这个属性和方法
- 于是又变成了下面代码的样子
public class Note {
public static void main(String[] args) {
//创建一个人对象
Person person = new Person();
person.name = "张三";//给这个对象的name属性赋值
person.age = 18;
person.country = "中国";
person.show();//调用这个对象的show方法
Person person1 = new Person();
person1.show();
}
}
class Person {
String name;
int age;
String country;
public void eat(){
System.out.println("I can eat");
}
public void sleep() {
System.out.println("I can sleep");
}
public void show(){
System.out.println("name:" + name + " age:" + age + " country:" + country);
}
}
输出:
name:张三 age:18 country:中国
name:null age:0 country:null
2.4 内存布局
2.5总结
类里面创建的叫成员属性和成员方法,或者叫实例变量和实例方法。这种属性可以不赋值,系统会赋默认值,比如上述代码的输出结果。
引用数据类型的null值:null在java中表示“空引用”,只有名字没有保存任何堆内存中地址,如果直接使用值为null的引用去操作“.”任何成员属性和成员方法,都会报错NullPointerException。
java中对象引用放在栈中,对象的实例放于堆中,一个对象要是只声明不赋值,则只会在内存的栈区创建引用,堆中并无此引用的指向。Person person2 = null;
person2.name = "z";
三、static关键字
看见static,与对象无关,是个公有,共有的含义
3.1 static修饰属性,类属性,类变量
- 当实例变量被static修饰,表示类的属性,该类的所有对象共享这一个属性。
- static修饰的属性在JVM方法区存储,所有该类对象共享此属性。
- 可以直接通过类名称访问该方法,无需通过对象访问。
- 当类加载到内存中时,该类的所有static变量就会被加载到方法区中
- 方法中不能定义静态变量。因为方法中的变量是局部变量在栈中存储,静态变量在方法区中存储,不可能一个变量存储在两个地方
- 若在类中定义了常量,一般使用static和final共同修饰,全局常量
- 一句话,一改全改,当类加载到内存中时,就可以通过类名访问该变量,没有创建对象也能访问!!!!
public class Note {
public static void main(String[] args) {
Person person = new Person();
person.name = "张三";
person.age = 18;
person.show();
System.out.println("-----------------------------------");
Person person1 = new Person();
person.country = "A国";
person.show();
person1.show();
System.out.println("-----------------------------------");
person.country = "B国";
person.show();
person1.show();
}
}
class Person {
String name;
int age;
static String country = "中国";
public void show(){
System.out.println("name = " + name + ",age = " + age + ",country = " + country);
}
}
输出:
name = 张三,age = 18,country = 中国
-----------------------------------
name = 张三,age = 18,country = A国
name = null,age = 0,country = A国
-----------------------------------
name = 张三,age = 18,country = B国
name = null,age = 0,country = B国
内存图:
3.2 static修饰方法,类方法,工具方法
- static修饰的方法是静态方法,没有对象也能调用
- 语法:类名称.方法名()
- 静态方法不能访问成员变量和成员方法。
- 成员方法能访问静态变量和静态方法。
- 普通的类不能通过static修饰,类定义的含义就是产生对象的。
public class Note {
public static void main(String[] args) {
Person person = new Person();
person.name = "张三";
person.age = 18;
person.show();
Person.fun();
}
}
class Person {
String name;
int age;
static String country = "中国";
static void fun(){
System.out.println("静态方法");
//show(); //error
System.out.println(country);
}
public void show(){
System.out.println("name = " + name + ",age = " + age + ",country = " + country);
}
}
输出:
name = 张三,age = 18,country = 中国
静态方法
中国
思考:为什么主方法是一个静态方法?
答:因为主方法若是个成员方法,一定是需要对象去访问的,此时我们还没创建对象,使用不了主方法,所以主方法一定是个静态方法。
3.3 static修饰代码块
代码块就是用{}括起来的一段代码
3.3.1 普通代码块
定义在方法中,使用{}括起来的代码块
public class Note {
public static void main(String[] args) {
//普通代码块
{
int x = 20;
}
int x = 10;
System.out.println("x = " + x);
}
}
输出:
x = 10;
3.3.2 成员代码块
- 定义在类中,使用{}括起来的代码块,也叫构造块
- 构造代码块优先于构造方法执行,有几个对象就调用几次构造块。
public class Note {
public static void main(String[] args) {
Person person = new Person();
Person person1 = new Person();
}
}
class Person {
private String name;
//构造快
{
System.out.println("1 构造快");
}
public Person(){
System.out.println("2 构造方法");
}
}
输出
1 构造快
2 构造方法
1 构造快
2 构造方法
3.3.3 静态代码块
定义在类中,使用使用static修饰的代码块,在类加载时执行一次
当定义类时,静态方法已经存放在方法区;当创建对象时,静态方法加载到方法区中
静态变量比构造方法优先使用
四、面向对象的封装特性,暂时学过private
封装的特点:保护性和易用性
比如我们将银行卡的卡号,密码封装起来,用户不可见,无法进行修改,这体现了封装的保护性
比如我们洗衣服,用户不需要知道怎么洗的,我们只要定义一个洗衣方法给用户,一键启动就可以了,这体现了封装的易用性。
4.1 修饰符权限
private < default(包访问权限) < protected < public
private:在当前类的内部可见,外部不可见,不能修饰外部类
public:对当前程序都是可见的
举例
如何让外部用户使用我们的方法,我们只要给用户我们想让用户使用的东西就可以了。
我们可以用set方法给用户一个设置的方法,用户调用这个方法,完成方法的内容。个体方法可以让用户得到一些可以让用户知道的变量值等,等于我们把这个变量分装起来了,提供一个方法给用户。
public class Note {
public static void main(String[] args) {
Bank bank = new Bank();
bank.setPassword();
}
}
class Bank {
private String card;
private String passwpord = "123456";
private double val;
public String getCard(){
return card;
}
public void setPassword(){
Scanner scanner = new Scanner(System.in);
int count = 0;
while(true){
System.out.println("输入原密码:");
String oldPass = scanner.nextLine();
if (oldPass.equals(passwpord)){
System.out.println("输入新密码");
passwpord = scanner.nextLine();
System.out.println("修改后的密码" + passwpord);
break;
}
count ++;
if (count == 3){
System.out.println("已输入错三次,失败");
break;
}
}
}
public double getVal() {
return val;
}
}
五、构造方法
- 使用new关键字其构造对象就是调用了该构造方法
- 构造方法的作用就是产生对象
- new一个对象分为两步:第一步:在堆中开辟一块内存空间;第二步:调用构造方法为成员变量赋值,不重新构造方法默认使用无参构造方法,赋默认值
5.1 构造方法的语法规则
- 构造方法的名字和类名相同
- 构造方法没有返回值声明
- 当类中没有重写构造方法,会自动产生一个无参构造
5.2 举例
构造方法就是方法的重载,是参数个数不同
当我们没有给成员变量赋值的时候,就是自动赋值为默认值
public class Note {
public static void main(String[] args) {
Person person = new Person();
person.show();
Person person1 = new Person("张三");
person1.show();
Person person2 = new Person("李四",18);
person2.show();
}
}
class Person {
private String name;
private int age;
public Person(){
//name = null;age = 0
System.out.println("这是无参构造方法");
}
public Person(String n){
//name = null;age = 0
name = n;
System.out.println("这是一个参数的有参构造");
}
public Person(String n,int num){
//name = null;age = 0
name = n;
age = num;
System.out.println("这是两个参数的有参构造");
}
public void show(){
System.out.println("name = " + name + ",age = " + age);
}
}
六、this关键字
this关键字的三个作用:
- 调用当前对象的成员变量
- 调用当前对象的方法(普通成员方法,构造方法的相互调用)
- 表示当前对象的引用
前提:程序设计的理念,编译器会找最近的相同名称的变量在哪,就近原则。
public class Note {
public static void main(String[] args) {
Person person = new Person("李四",18);
person.show();
}
}
class Person {
private String name;
private int age;
public Person(String name,int age){
this.name = name;
this.age = age;
System.out.println("这是两个参数的有参构造");
}
public void show(){
System.out.println("name = " + name + ",age = " + age);
}
}
这个代码里的this可以找到当前类的成员变量,即上面讲的第一个作用
class Person {
private String name;
private int age;
public Person(String name,int age){
this.name = name;
this.age = age;
System.out.println("这是两个参数的有参构造");
}
public void fun(){
this.fun();
}
public void show(){
System.out.println("name = " + name + ",age = " + age);
}
}
这里的this可以找到当前对象的成员方法,即上面讲的第二个作用的普通成员方法
class Person {
private String name;
private int age;
public Person(){
System.out.println("!!!!!");
}
public Person(String name){
this();
}
public Person(String name,int age){
this(name);
this.age = age;
}
}
这个的this调用有参构造方法,但有二个条件,调用有参构造不能形成环,this调用其他有参构造方法必须放在首行。
七、匿名类
new出来的对象,使用一次后销毁,没有引用指向。
语法:new 类名()
public class Note {
public static void main(String[] args) {
System.out.println(new Person("张三"));
}
}
class Person {
String name;
public Person(String name){
this.name = name;
}
}
输出
Person@1b6d3586 //这是引用类型的地址
八、toString方法
在打印对象时,会默认调用toString方法,我们可以将其重写,输出自己想要的结果。
System.out.println(对象名); //默认调用toString方法
public class Note {
public static void main(String[] args) {
System.out.println(new Person("张三"));
}
}
class Person {
String name;
public Person(String name){
this.name = name;
}
public String toString(){
String ret = "name = " + this.name;
return ret;
}
}