本系列博客汇总在这里:Java系列_汇总
目录
- 一、面向过程
- 二、面向对象
- 三、类
- 四、如何给一个具体的对象来赋值属性呢
- 五、对象方法的调用
- 六、局部变量和成员变量
- 七、匿名对象
- 八、封装
- 九、程序执行流程说明
- 十、构造器
一、面向过程
例:五子棋游戏的开发
1.开始
2.白字先走
3.绘制棋盘
4.判断输赢
5.黑子先走
6.绘制棋盘
7.判断输赢
。。。。例:把大象装进冰箱里
1.打开冰箱
2.放入大象
3.关闭冰箱
二、面向对象
面向对象的思想是抽取一类具有相同属性和行为的事物。
棋子:走,黑子和白子
棋盘:绘制
规则:判定输赢冰箱:开门,关门
大象:走路编程就是模拟生活,万物皆对象(只有八种数据类型不是对象)。
三、类
类:属性和行为相同的事物抽象成一类。
例如:狗
属性:颜色,眼睛,耳朵,重量
行为:看家,睡觉例如:车
属性:颜色,四个轮子,方向盘
行为:跑,刹车类就是一个概念,是抽象的,如,狗。
对象就是一个具体的实物,如,哈士奇。
类就是一个模板的东西,对象(实例)是根据各个模板所产生的样本。
语法
class 类名
{
属性;
行为;
}命名规范
类名和文件名要一致,首字母要大写,如果是多个单词组成每个单词的首字母都要大写。属性(成员变量)的定义
格式:数据类型 属性名 = [ 初始值 ];// [] 里的可以没有,也就是说,属性可以没有初始值。
类方法的定义
public [static] 返回值类型[void] 方法名(数据类型 参数名,...)
{
...
return 数据;
}类是一个概念,不能直接使用,必须使用这个类的对象,根据类来创建对象。
语法格式:
类名 (数据类型) 变量名 = new 类名 ();
一个文件可以有多个类,但是实际工作中没有人在一个文件中使用多个类。
四、如何给一个具体的对象来赋值属性呢
语法格式:对象的变量.属性名 = 具体指;
对象创建的内存结构
栈内存:存取速度快,存取空间小,先进后出;存储8种数据类型的数据
堆内存:存取速度慢,存取空间大;存储的是对象,数组是在堆中存储的流程说明
将主类 class 文件载入到 java 的虚拟机内,然后将方法区的 main 方法调进栈,开始执行 main 方法里的逻辑,开始创建对象,Dog dog = new Dog(); ,此对象产生在堆中,附带属性,就会在堆内存里有一个地址 0X99(假设),由于 dog 是一个变量名,它在栈内存里也会有一个地址0X99,而这个地址就是 dog,在给 dog 的属性赋值时,栈内存里的地址会指向堆内存里的地址,找到 dog 的属性后相应进行赋值,color 从 null 变为黄色,height 从 0.0 变为 20,其他属性同样如此。当又创建一个 dog1 时, 会立马在堆内存里又开辟一个空间,同时,它也会有一个地址0X98(假设),同样 dog1 在栈内存里也会有一个地址 0X98,此时的这个 dog 在并未赋值属性时,它的属性依然是 null 或者 0.0;这就需要再给这个新创建的这个 dog1 的属性进行赋值,赋值完成之后,新的 dog1 就创建出来了。
主方法执行完毕后需要出栈,创建的 dog 和 dog1 都会先后出栈消失,主方法最后出栈。而堆内存里的东西依靠 java 的垃圾回收机制也会被清理。示例
public class Welcome
{
public static void main(String[] args)
{
System.out.println("---------------第一只狗-----------------------------");
//注意:在dog类中的属性没有加private时,此处是可以改类的属性的,但是加了private后在此处是不能对其赋值以及访问的
Dog dog = new Dog();
dog.color = "黄色";
dog.name = "小黄";
dog.height = 0.5;
dog.weight = 20;
System.out.println("我叫"+dog.name+",我是"+dog.color+"的,我的身高是"+dog.height+"米,我的体重是"+dog.weight+"千克!");
dog.protect();
System.out.println("---------------第二只狗-----------------------------");
Dog dog1 = new Dog();
dog1.color = "黑色";
dog1.name = "小黑";
dog1.height = 0.5;
dog1.weight = 10;
System.out.println("我叫"+dog1.name+",我是"+dog1.color+"的,我的身高是"+dog1.height+"米,我的体重是"+dog1.weight+"千克!");
dog1.sleep();
}
}class Dog
{
//Dog的属性
String name;
String color;
double height;
double weight;
//有如下方法
public void protect()
{
System.out.println("我在看家");
}
public void sleep()
{
System.out.println("我在睡觉");
}
}
五、对象方法的调用
- 语法格式:
对象的变量名的名字 . 方法名 ( [ 参数 ] );
- 说明
调用 protect,那么 protect 方法就会从方法区进栈,那个对象调用的 protect 方法,这个方法里将要使用的属性就是谁的,比如 dog1 调用了此方法,那么此方法里的 name 就是 dog1 在堆内存里所指向的属性值。 - 注意
当把 dog1 的值赋给 dog2 时,dog2 就会指向 dog1 的所指向的地址,在执行dog2.color = “白色”;时,所改掉的属性是原来 dog1 的属性,此时如果再打印 dog1,它的属性就不是原来的属性了,而是 dog2 刚改掉的属性。
六、局部变量和成员变量
局部变量
(1)在方法中或者语句块中。
(2)局部变量必须赋初始值,不赋值的话,编译能过,运行不能过。
(3)都存储在栈中。
(4)生命周期:定义的时候产生,当前方法或语句块结束时就会消失。成员变量
(1)只能在类的直接一层里,类里的方法里也不行。
(2)可以不赋值,如果不赋值都有默认值(初始值)。
(3)存储在堆中。
(4)生命周期:随着对象的消失而消失,对象一消失,堆内存里的成员变量就会变成匿名对象,会被 jvm 的垃圾回收机制来回收掉。示例
public static void main(String[] args)
{
Dog dog = new Dog();
}
//这里的 dog 就是局部变量static
{
int i=0;
}
//这里的 i 也是局部变量
七、匿名对象
- new Dog(); 和 Dog dog=new Dog(); 是不一样的
- 示例
- 这样的话就产生了两个对象,这样是赋值不了的,这就是匿名对象,匿名对象是没有意义的,由于栈中没有一个变量对它做引用,很快就会被垃圾回收器回收掉,所以前面必须给数据类型,实际开发中要避免匿名对象。
//new Dog();不能像如下这样用
new Dog().name = ”小黑”;
new Dog().color = ”白色”;
八、封装
将属性私有化,使用 private 关键字完成属性私有化,这种属性只有本类能访问。
目的:提高数据的安全性
类中的属性一旦加了 private,该类的属性就被封装起来了,其他类想用这个属性的话,只能通过 “接口” 才能访问。那么,此处的 “接口” 是什么呢?“接口” 就是在具有私有属性的类中加 public,public 是所有类都可以访问的,通过在这个类中设置 public(如图1),这样就可以将值传递给 public,在这个 public 里实现对所在类的私有属性进行修改;同理也可以设置一个 public 来返回私有属性的值(如图2),这样我们在外边调用这个 public 方法,就可以获得私有属性的值了。
图1
图2示例
public class Welcome
{
public static void main(String[] args)
{
Student student=new Student();
//在Student类中的属性没有加private时,也就是没有封装起来的,此处是可以改类的属性的,
//但是加了private后在此处是不能对其赋值以及访问的。
//student.name="张三";
//student.gender="男";
//student.age=20;
//设置
student.setName("李四");
student.setGender('男');
student.setAge(20);
//获取
String name = student.getName();
char gender = student.getGender();
int age= student.getAge();
System.out.println("-------------获得私有属性-----------------------");
System.out.println("我叫"+name+" 性别:"+gender+" 年龄是:"+age);
System.out.println("-----------------调用---------------------------");
student.introduce();
}
}class Student
{
/**
* 姓名
*/
private String name;
/**
* 性别
*/
private char gender;
/**
* 年龄
*/
private int age;
//以上三个属性在本类里可以直接访问,在其他类里不能直接访问
public void introduce()
{
System.out.println("我叫"+name+" 性别:"+gender+" 年龄是:"+age);
}
/**
*通过 public 对外公开的 get 和 set 方法来获得和设置私有的属性值
*/
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public char getGender()
{
return gender;
}
public void setGender(char gender)
{
this.gender = gender;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
}
九、程序执行流程说明
- 示例
-
- 流程说明
(1)第一步:编译完成运行时,把 Welcome.class 载入到 jvm,把 main 放入方法区,再把 main 方法压栈。
(2)第二步:加载 Car.class 进入 jvm,然后把 run 方法和 introduce 方法加载到方法区,在堆中开辟一个空间创建了一个 Car 对象,在栈中产生一个变量 Car 指向堆中的对象。然后给 Car 对象三个属性赋值。
(3)第三步:car 的 run 方法进栈,把 car 变量所指向的地址赋值给 this 关键字,执行方法体。
(4)第四步:run 方法出栈,run 中的 this 消失。
(5)第五步:car 变量消失,main 方法出栈后消失
(6)第六步:由于 car 堆中的对象失去了变量的引用变成了匿名对象,所以也被回收。
public class Welcome
{
public static void main(String[] args)
{
Car car=new Car();
//给car对象的属性赋值
car.color = "黄色";
car.carNo = 88888;
car.name = "大黄蜂";
System.out.println("----------------打印对象----------------------------");
System.out.println(car.name);
System.out.println("----------------调用run方法-------------------------");
car.run();
System.out.println("----------------调用introduce方法-------------------");
car.introduce();
}
}
class Car
{
//未封装
String color;
int carNo;
String name;
public void run()
{
System.out.println(this.name);
//谁调用run,这里的this指调用run的对象的本身,所以这里run被创建的对象调用以后,this.name就是这个对象里的name属性
}
public void introduce()
{
System.out.println("我是一辆车牌是"+this.carNo+this.color+this.name+"车");
//同上理
}
}
十、构造器
构造器其实就是一种方法,一种创建对象的方法,语法格式如下
public 类名(数据类型 参数名,…)
{
//public处可以有private替换
}目的:创建对象。
之前通过 new 创建的对象,其属性是空的。
而构造器就不一样了,直接可以通过传参数的方法直接创建一个属性不为空的对象。
构造器特点
(1)方法名与类名一致
(2)方法没有返回值没有void
(3)参数可有可无示例
public class Welcome
{
public static void main(String[] args)
{
System.out.println("-----------------------------------");
Person p = new Person("刘备");
//此行代码就是调用了构造器Person,没有显式的写构造器也能用。那是因为java提供了一个隐含的构造器,显式的写出来后,之前隐含的构造器就会被覆盖掉
System.out.println(p.name);
System.out.println(p.age);
System.out.println(p.gender);
p.introduce();
System.out.println("-----------------------------------");
Person p1 = new Person("关羽",1);
System.out.println(p1.name);
System.out.println(p1.age);
System.out.println(p1.gender);
p1.introduce();
System.out.println("-----------------------------------");
Person p2=new Person("张飞",2,'男');
System.out.println(p2.name);
System.out.println(p2.age);
System.out.println(p2.gender);
p2.introduce();
}
}class Person
{
/**
* 姓名
*/
String name;
/**
* 性别
*/
char gender;
/**
* 年龄
*/
int age;
//带一个参数的构造器
public Person(String name)
{
this.name=name;
}
//带两个参数的构造器
public Person(String name,int age)
{
//调用一个参数的构造器
this(name);
this.age=age;
}
//带三个参数的构造器
public Person(String name,int age,char gender)
{
//调用两个参数的构造器
this(name,age);
this.gender=gender;
}
public void introduce()
{
System.out.println("我叫"+name+" 性别:"+gender+" 年龄:"+age);
}
}注意
(1)之前 new 就是调用了构造器,只是因为没有显式的写出构造器也能用,那是因为 java 提供了一个隐含的构造器。当使用带参数的构造器时,之前隐含的构造器就会被覆盖掉,再次想要使用这个被覆盖的隐式的构造器的话,就要先显式的写出来才能用了。
(2)通过 this(实参列表);可以调用本类中的构造器,但必须注意,this 必须在方法中的第一行处。
如有错误,欢迎指正!