Java-面向对象
一、类和对象
1、类和对象的关系
万事万物皆对象
对象就是具体的事物,具体的实体,具体的实例,模板下具体的产品。
类:类是抽象的,是一个模板。
2、创建类
java
package com.company.TestOOP;
public class Person {
//名词------》属性------》成员变量------》放在类中,方法外
String name;
int age;
double weight;
double height = 175;
//动词------》方法
//吃饭
public void eat() {
int num = 20; //局部变量,放在方法中,必须进行初始化
System.out.println("吃饭");
}
public void sleep(String address) {
System.out.println("我在睡觉地点在:" + address);
}
//自我介绍
public String interduce() {
return "我的名字是:" + name + ",我的年龄" + age + ",我的身高是:" + height + ",我的体重是:" + weight;
}
}
3、创建对象
第一次加载类的时候,会进行类的加载,初始化创建对象的时候,对象的属性没有给赋值,有默认的初始化的值。
再次创建对象时,就不会进行类的加载了,类的加载只在第一次需要的时候加载一次。
不同的对象,属性有特有的值,但是方法都是调用类中通用的方法。
对象的属性是独立的方法;
各个对象的方法是共享的。
java
package com.company.TestOOP;
public class Test {
public static void main(String[] args) {
//创建一个人类的具体的对象/实例:
//Person属于引用数据类型
//创建一个对象,对象的名字叫zs
//第一次加载类的时候,会进行类的加载,初始化创建对象的时候,对象的属性没有给赋值,有默认的初始化的值
Person zs = new Person();
zs.name="kobe";
zs.age=19;
zs.height=180;
zs.weight=170;
//再次创建对象时,就不会进行类的加载了,类的加载只在第一次需要的时候加载一次。
Person ls = new Person();
ls.name="james";
ls.age=19;
ls.height=180;
ls.weight=170;
System.out.println(ls.name);
System.out.println(zs.name);
//不同的对象,属性有特有的值,但是方法都是调用类中通用的方法。
//属性,各个对象的属性是独立的
//方法:各个对象的方法是共享的
ls.eat();
zs.eat();
zs.sleep("酒店");
String s = ls.interduce();
System.out.println(s);
}
}
java
james
kobe
吃饭
吃饭
我在睡觉地点在:酒店
我的名字是:james,我的年龄19,我的身高是:180.0,我的体重是:170.0
4、成员变量与局部变量
区别:
1、代码中位置不同:
成员变量:在类中,方法外。
局部变量:方法中定义的变量,代码块中定义的变量
2、代码的作用范围
成员变量:当前类的很多方法
局部变量:当前一个方法(当前代码块)
3、是否有默认值
成员变量:有
局部变量:无
4、是否要初始化
成员变量:不需要,不建议初始化,后续使用的时候再赋值即可。
局部变量:一定需要,不然使用的时候直接报错。
5、内存中位置不同
成员变量:堆内存
局部变量:栈内存
6、作用时间不同
成员变量:当前对象从创建到销毁
局部变量:当前方法从开始执行到执行完毕
5、构造器
5.1、创建对象的过程
1、第一次遇到Person的时候,进行类的加载(并且只加载1次)
2、创建对象,为这个对象在堆中开辟空间
3、为对象进行属性的初始化动作
new关键字实际上是在调用一个方法,这个方法叫构造方法(构造器)。
调用构造方法的时候,如果你的类中没有写构造器,那么系统会默认分配一个构造器,只是我们看不到罢了。
可以自己显示的将构造器编写出来。
5.2、构造器的格式
java
[修饰符] 构造器名字(){
}
5.3、构造器和方法的区别
1、没有方法的返回值类型
2、方法体内部不能有return
3、构造器的名字很特殊,必须和类名一模一样
5.4、构造器的作用
不是为了创建对象,因为在调用构造器之前,这个对象已经创建好了,并且属性有默认的初始化的值。
调用构造器的目的:是给属性进行赋值操作
注意:一般不会在空构造器中进行初始化操作,因为那样的话每个对象的属性就一样了。
实际上:我们只要保证空构造器的存在就可以了,里面的东西不用写。
java
package com.msb;
public class Person {
//属性
String name;
int age;
double height;
//构造器:没有任何参数的构造器;空参构造器
public Person(){
//注意:一般不会在空构造器中进行初始化操作,因为那样的话每个对象的属性就一样了。
// age = 19;
// name = "kobe";
// height = 180;
}
//方法
public void eat(){
System.out.println("吃饭");
}
}
java
package com.msb;
public class Test {
public static void main(String[] args) {
//创建一个Person类的具体的对象/实例/实体
/*
创建对象的过程:
1、第一次遇到Person的时候,进行类的加载(并且只加载1次)
2、创建对象,为这个对象在堆中开辟空间
3、为对象进行属性的初始化动作
new关键字实际上是在调用一个方法,这个方法叫构造方法(构造器)
调用构造方法的时候,如果你的类中没有 写构造器,那么系统会默认分配一个构造器,只是我们看不到罢了
可以自己显示的将构造器编写出来。
构造器的格式:
[修饰符] 构造器名字(){
}
构造器和方法的区别:
1、没有方法的返回值类型
2、方法体内部不能有return
3、构造器的名字很特殊,必须和类名一模一样
构造器的作用:不是为了创建对象,因为在调用构造器之前,这个对象已经创建好了,并且属性有默认的初始化的值。
调用构造器的目的:是给属性进行赋值操作
注意:一般不会在空构造器中进行初始化操作,因为那样的话每个对象的属性就一样了。
实际上:我们只要保证空构造器的存在就可以了,里面的东西不用写。
*/
Person zs = new Person();
System.out.println(zs.age);
System.out.println(zs.name);
}
}
5.5、构造器的重载
当形参名字和属性名字重名的时候,程序有就近原则
在要表示对象的属性前加上this关键字,this表示当前对象;
java
package com.msb1;
public class Person {
//属性
String name;
int age;
double height;
//构造器:没有任何参数的构造器;空参构造器
public Person() {
}
public Person(String name, int age, double height) {
//当形参名字和属性名字重名的时候,程序有就近原则
//在要表示对象的属性前加上this关键字,this表示当前对象;
this.name = name;
this.age = age;
this.height = height;
}
public Person(String a, int b) {
name = a;
age = b;
}
//方法
public void eat() {
System.out.println("吃饭");
}
}
1、一般保证空构造器的存在,空构造器中一般不会进行属性的赋值操作。
2、一般我们会重载构造器,在重载的构造器中进行属性赋值操作。
3、在重载构造器以后,假如空构造器忘记写了,系统也不会给你分配默认的空构造器了,那么调用的时候就会出错。
java
package com.msb1;
public class Test {
public static void main(String[] args) {
/*
1、一般保证空构造器的存在,空构造器中一般不会进行属性的赋值操作。
2、一般我们会重载构造器,在重载的构造器中进行属性赋值操作。
3、在重载构造器以后,假如空构造器忘记写了,系统也不会给你分配默认的空构造器了,那么调用的时候就会出错。
*/
Person zs = new Person("kobe", 20, 180);
System.out.println(zs.name);
System.out.println(zs.age);
System.out.println(zs.height);
}
}
6、this关键字用法:
1、在第一次遇到一个类的时候,对这个类进行加载,只加载一次。
2、创建对象,在堆中开辟空间。
3、对对象进行初始化操作,属性赋值都是默认的初始值。
4、new关键字调用构造器,执行构造器方法,对对象的属性进行重新赋值。
从上面的效果可以看到,this指代的就是当前对象。内存如下
6.1、this可以修饰属性
总结:
当属性名字和形参发生重名的时候,或者属性名字和局部变量重名的时候,都会发生就近原则,所以如果我要直接使用变量名字指的是离得近的形参或者局部变量。如果我想要表示属性的话,在前面要加上this.修饰
如果不发生重名问题的话,实际上你要是访问属性也可以省略this.不写
java
package com.msb2;
public class Test {
public static void main(String[] args) {
//创建一个Person类的具体对象
Person p = new Person(19,"kobe",180);
p.eat();
}
}
java
package com.msb2;
public class Person {
//属性
int age;
String name;
double height;
//空构造器
public Person() {
}
//有参构造器
public Person(int age, String name, double height) {
this.age = age;
this.name = name;
this.height = height;
}
public void eat() {
int age = 10;
System.out.println(age); // 就近原则10
System.out.println(this.age); //这里指代的是属性的age
System.out.println("吃饭");
}
}
6.2、this可以修饰方法
总结:在同一个类中,方法可以互相调用,this.可以不写
java
package com.msb2;
public class Test {
public static void main(String[] args) {
//创建一个Person类的具体对象
Person p = new Person(19,"kobe",180);
p.eat();
}
}
java
package com.msb2;
public class Person {
//属性
int age;
String name;
double height;
//空构造器
public Person() {
}
//有参构造器
public Person(int age, String name, double height) {
this.age = age;
this.name = name;
this.height = height;
}
public void eat() {
int age = 10;
System.out.println(age); // 就近原则10
System.out.println(this.age); //这里指代的是属性的age
System.out.println("吃饭");
}
public void play() {
this.play1(); //this可以省略不写
System.out.println("吃饭");
System.out.println("学习");
System.out.println("睡觉");
}
public void play1() {
System.out.println("学习");
}
}
6.3、this可以修饰构造器
总结:同一个类中的构造器可以相互用this调用,注意,this修饰构造器必须放到第一行。
java
package com.msb2;
public class Person {
//属性
int age;
String name;
double height;
//空构造器
public Person() {
}
//有参构造器
public Person(int age, String name, double height) {
this.age = age;
this.name = name;
this.height = height;
}
//有参构造器
public Person(int age, String name) {
this(age);
this.name = name;
}
//有参构造器
public Person(int age) {
this.age = age;
}
public void eat() {
int age = 10;
System.out.println(age); // 就近原则10
System.out.println(this.age); //这里指代的是属性的age
System.out.println("吃饭");
}
public void play() {
this.play1(); //this可以省略不写
System.out.println("吃饭");
System.out.println("学习");
System.out.println("睡觉");
}
public void play1() {
System.out.println("学习");
}
}
7、static
static可以修饰:属性、方法、代码块、内部类
7.1、static修饰属性
java
package com.mas_static;
public class Test {
//属性
int id;
static int sid;
public static void main(String[] args) {
//创建对象
Test t1 = new Test();
t1.id = 10;
t1.sid = 10;
Test t2 = new Test();
t2.id = 20;
t2.sid = 20;
Test t3 = new Test();
t3.id = 30;
t3.sid = 30;
//读取属性的值
System.out.println(t1.id);
System.out.println(t2.id);
System.out.println(t3.id);
System.out.println(t1.sid);
System.out.println(t2.sid);
System.out.println(t3.sid);
}
}
7.1.1、static静态域示意图
一般官方的推荐访问方式:类名.属性名
static修饰总结:
1、在类加载的时候一起加载入方法区中的静态域中
2、先于对象存在
3、访问方式:对象名.属性名 类名.属性名
7.1.2、static修饰属性的应用创建
某些特定的数据,想要在内存中共享,只有一块------》这个情况下,使用static修饰。
java
package com.mas_static;
public class MSBStudent {
String name;
int age;
static String school;
public static void main(String[] args) {
MSBStudent.school = "qh";
MSBStudent s1 = new MSBStudent();
s1.name = "kobe";
s1.age = 20;
// s1.school = "qh";
MSBStudent s2 = new MSBStudent();
s2.name = "kobe";
s2.age = 20;
// s2.school = "qh";
System.out.println(s2.school);
}
}
属性:
静态属性(类变量、类属性)
非静态属性(实例变量、实例属性)
2、static修饰方法
1、static和public都是修饰符,并列的没有先后顺序,先写谁后写谁都可以
2、在静态方法中不能访问非静态的属性
3、在静态方法中不能访问非静态的方法
4、在静态方法中,不能使用this关键字
5、非静态的方法可以使用对象名.方法名去调用
6、静态的方法可以使用 对象名.方法名去调用 也可以用类名.方法名去调用
java
package com.mas_static;
public class Demo {
int id;
static int sid;
public void a(){
System.out.println("------a");
System.out.println(id);
System.out.println(sid);
}
//1、static和public都是修饰符,并列的没有先后顺序,先写谁后写谁都可以
public static void b(){
// System.out.println(this.id); //在静态方法中,不能使用this关键字
// a(); //在静态方法中不能访问非静态的方法
System.out.println("------b");
// System.out.println(id); //在静态方法中不能访问非静态的属性
System.out.println(sid);
}
public static void main(String[] args) {
//非静态的方法可以使用对象名.方法名去调用
Demo d =new Demo();
d.a();
//非静态的方法可以使用 对象名.方法名去调用 也可以用类名.方法名去调用
Demo.b();
d.b();
}
}
8、代码块
代码块分为:普通块、构造块、静态块、同步块(多线程)
总结:
8.1、代码块执行顺序:
最先执行静态块,并且只在类加载的时候只执行一次,所以一般一九实战写项目:创建工厂、数据库初始化信息,一般用于执行全局性的初始化操作。
再执行构造块。(不常用)
再执行构造器。
再执行方法中的普通块。
java
package com.msb3;
public class Test {
//属性
int a;
static int sa;
//方法
public void a(){
System.out.println("a");
{
//普通块限制了局部变量的作用范围
System.out.println("这是普通块");
int num = 1;
System.out.println(num);
}
}
//静态方法
public static void b(){
System.out.println("b");
}
//构造块
{
System.out.println("这是构造块");
}
//静态块
static {
//在静态块中只能访问静态方法,静态属性
System.out.println("这是静态块");
System.out.println(sa);
b();
}
public Test(){
System.out.println("这是空构造器");
}
//构造器
public Test(int a){
this.a=a;
}
public static void main(String[] args) {
Test t= new Test();
t.a();
Test t1= new Test();
t1.a();
}
}
java
这是静态块
0
b
这是构造块
这是空构造器
a
这是普通块
1
这是构造块
这是空构造器
a
这是普通块
1
Process finished with exit code 0