第四章 面向对象(上)
1、面向对象思想概述
1、面向对象与面向过程的区别?
面向过程的思想:代表语言 C语言 功能开发中的每一步都是自己参与的
面向对象的思想:代表语言 java语言 指的是不断地创建对象,指挥对象事情过程
2、举例现实生活中的例子:
接水:
面向过程的思想:自己拿起水杯,自己走到饮水机面前,自己接水。
面向对象的思想:祈求同桌接水,同桌拿起水杯,同桌走到饮水机面前,同桌接水。
3、伪代码的例子
将大象装进冰箱
面向过程的思想:
class Demo{
public static void main(String[] args){
//打开冰箱门
//实际上打开冰箱门的功能代码量是很多的
//大象跳进冰箱
//实际上大象跳进冰箱的功能代码量是很多的
//关闭冰箱门
}
}
面向对象的思想:
1、都有那些事物?
判断事物的方式:
1)UML课程知识
2)名词提取法
大象,冰箱,测试类
2、事物中都有些什么?
大象:
属性:身高,体重,性别....
行为:跳进冰箱,吃饭,睡觉....
冰箱:
属性:颜色,容量,大小...
行为:打开冰箱门,关闭冰箱门...
测试类:
main方法
3、事物和事物之间的关系是什么?
在测试类中创建大象对象和冰箱对象。
class 大象{
身高;
体重;
跳进冰箱(){
//...
}
吃饭(){
//...
}
睡觉(){
//...
}
}
class 冰箱{
颜色;
容量;
大小;
打开冰箱门(){
}
关闭冰箱门(){
}
}
class Test{
public static void main(String[] args){
//创建一个大象对象
//创建一个冰箱对象
//调用冰箱对象中的打开冰箱门的方法
//调用大象对象中的跳进冰箱的方法
//调用冰箱对象中的关闭冰箱门的方法
}
}
4、类和对象的关系
类:相当于汽车图纸
对象:相当于通过图纸造出来的一辆车
5、面向对象的三大特征:
封装
继承
多态
2、标准类的1.0写法 - 3.0写法
/*
我们按照今天说的类和对象的知识,创建了一个Person对象,并且也成功赋值了姓名和年龄
但是我们可以赋值一些不合实际的数值,这是不应该出现,所以我们应该在赋值之前,要先判断一下要赋的值是否合理
既然是加判断,就不是一句话可以搞定的,我们可以定义一个方法,使用方法对成员变量赋值
我们确实可以通过加一个方法来对成员变量进行赋值,但是谁规定了我必须要用这个方法呢?我们依旧可以使用原来的方式进行赋值
我们如果可以通过一些手段,让外界无法直接获取成员变量,这样就不得不使用方法进行赋值了。
java提供一个关键字给我们使用:private 私有的
private关键字:
可以修饰成员变量,成员方法,构造方法
在同一个类中,private关键字不起作用,相当于透明的,同一个类中被private关键字修饰的成员可以随意访问
说到现在,其实说的就是面向对象编程三大特征之一:封装
封装: 使用private关键字将类中细节进行隐藏,只对外提供公共的访问方式。
一个标准类的写法:最终是4.0版本
1.0版本的写法:使用private关键字修饰成员变量
类:
成员变量:使用private关键字修饰
成员方法:针对每一个成员变量提供对应公共的setXxx()和getXxx()
*/
class Person {
private String name;
private int age;
public String getName(){
return name;
}
public void setName(String n){
name = n;
}
public int getAge(){
return age;
}
public void setAge(int i) {
if (i > 0 && i <= 130) {
age = i;
}else {
System.out.println("输入的年龄不合实际!");
}
}
private void fun1(){
System.out.println("好好学习,天天向上!");
}
public void show1(){
fun1();
}
}
public class PersonDemo {
public static void main(String[] args) {
//创建一个Person类的对象
Person p1 = new Person();
// System.out.println("姓名:" + p1.name);
// System.out.println("年龄:" + p1.age);
System.out.println("姓名:" + p1.getName());
System.out.println("年龄:" + p1.getAge());
System.out.println("-------------------------");
// p1.name = "江川";
// p1.age = 1800;
p1.setAge(1800);
p1.setName("江川");
// System.out.println("姓名:" + p1.name);
// System.out.println("年龄:" + p1.age);
System.out.println("姓名:" + p1.getName());
System.out.println("年龄:" + p1.getAge());
System.out.println("------------------------");
// p1.fun1();
p1.show1();
}
}
============================================================
/*
一个标准类的写法2.0版本
成员变量:使用private关键字修饰
成员方法:针对每一个成员变量都提供getXxx()和setXxx(),其中参数需要见明知意,需要使用this关键字辅助
show()方法:展示当前对象的所有成员变量值
*/
public class Student2 {
private String name;
private int age;
private String gender;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public void show() {
System.out.println("姓名:" + this.name + ", 年龄:" + this.age + ", 性别:" + this.gender);
}
}
class Demo2{
public static void main(String[] args) {
Student2 s1 = new Student2();
s1.setName("江川");
s1.setAge(18);
s1.setGender("男");
s1.show();
}
}
============================================================
/*
构造方法的用处:
1、用于创建对象
2、可以给对象中成员变量进行赋值
*/
//一个标准类的3.0版本的写法
/*
类:成员
成员变量:私有化
构造方法:一个无参,一个所有参数
成员方法:setXxx()和getXxx()
show方法:展示对象所有成员变量值
*/
public class Student4 {
private String id;
private String name;
private int age;
Student4(){
}
Student4(String id,String name,int age){
this.id = id;
this.name = name;
this.age = age;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void show() {
System.out.println("学号:" + id + ", 姓名:" + name + ", 年龄:" + age);
}
}
class Demo4 {
public static void main(String[] args) {
//通过无参的构造方法创建对象,使用setXxx对成员变量赋值
// Student4 s1 = new Student4();
// s1.setName("江川");
// s1.setId("1001");
// s1.setAge(18);
// s1.show();
//直接通过有参的构造方法对成员变量进行赋值
Student4 s2 = new Student4("1002","江川",19);
s2.show();
}
}
============================================================
成员变量和成员方法
import java.util.Scanner;
/*
学生: class Student:
属性:姓名,年龄,性别 成员变量:name,age,gender
行为:吃饭,睡觉 成员方法:eat(){},sleep(){}
*/
public class Student {
//成员变量,定义在类中方法外
String name;
int age;
String gender;
//成员方法
public void eat() {
System.out.println("吃饭");
}
public void sleep() {
System.out.println("睡觉");
}
}
class Demo1 {
public static void main(String[] args) {
//创建一个学生对象
//如何通过一个类创建一个对象
// 语法格式:类名 对象名 = new 类名();
Student s1 = new Student();
//获取对象中的成员变量
//对象名.成员变量名
String n1 = s1.name;
System.out.println("姓名:" + n1);
s1.name = "江川";
System.out.println("姓名:" + s1.name);
//如何使用对象中的成员方法
// eat();
//对象名.成员方法名()
s1.eat();
s1.sleep();
}
}
============================================================
匿名类:
//定义一个教师类
class Teacher {
public void fun2(){
System.out.println("好好学习,天天向上!");
}
}
class Demo2{
//当你今后看到一个类作为方法的参数的时候,将来调用时需要传入该类的对象【或者该类的子类对象】
public void method(Teacher t){ //Teacher t = new Teacher()
t.fun2();
}
}
public class TeacherDemo1 {
public static void main(String[] args) {
Demo2 d1 = new Demo2();
// Teacher t1 = new Teacher();
d1.method(new Teacher()); // new Teacher()
//匿名对象,指的是没有名字的对象,只能用一次,后续无法继续使用该对象
// d1.method(new Teacher());
}
}
3、static关键字 this关键字
/*
1. 被static修饰的成员,称之为类成员,在对象创建之前就存在于方法区中静态区
2. 被static修饰的成员,可以通过类名直接访问使用,非静态的成员必须要通过对象去调用
3. static可以修饰成员变量和成员方法
4. 非静态的成员方法既可以访问静态的成员[变量或方法],也可以访问非静态的成员[变量或方法]
5. 静态的成员方法只能访问静态的成员[变量或方法]
6. 静态的成员方法不能使用this关键字的
*/
class Demo7{
int a = 10;
static int b = 20;
public void fun1(){
// System.out.println(a);
// System.out.println(b);
// show1();
// show2();
int a = 30;
System.out.println(this.a);
}
public static void fun2(){
// System.out.println(a);
// System.out.println(b);
// show2();
// show1();
int a = 40;
// System.out.println(this.a);
// Demo7 demo7 = new Demo7();
// System.out.println(demo7.a);
}
public static void show2(){
System.out.println("这是静态的成员方法");
}
public void show1(){
System.out.println("这是非静态的成员方法");
}
}
public class StaticDemo {
public static void main(String[] args) {
Demo7 demo7 = new Demo7();
// demo7.fun1();
// demo7.fun2();
Demo7.fun2();
}
}
============================================================/*
this: 代表的是调用当前方法的对象
this可以使用对象中的成员变量,成员方法,构造方法
*/
class Test1{
int a = 10;
public void fun1(){
int a = 20;
//先在方法中寻找,若找不到去成员变量位置查找
//在一个方法中是无法访问另一个方法中定义的东西
System.out.println(a);
System.out.println(this.a); //获取当前对象中的成员变量a
this.fun2(); // 同一个类,方法内部可以调用该类中其它的方法
}
public void fun2(){
int a = 30;
System.out.println(a);
}
}
public class ThisDemo1 {
public static void main(String[] args) {
Test1 test1 = new Test1();
test1.fun1();
}
}
4、帮助文档
import java.util.Scanner;
/*
帮助文档的学习:
1、打开帮助文档
2、点击索引,搜索想要查询的类
3、看什么包下的,除了在java.lang包下的类不用导包以外,其它任意包下的类在使用之前都需要导包
4、看类的关系图
5、看类的描述
6、看有无构造方法
若看到一个类中没有构造方法,大概率这个类是工具类,方法被static修饰
7、若有构造方法,就可以根据构造方法创建对象了
8、看成员变量
9、查找自己需要的方法并使用
*/
public class DocDemo {
public static void main(String[] args) {
//Scanner(InputStream source)
//构造一个新的 Scanner ,产生从指定输入流扫描的值。
Scanner sc = new Scanner(System.in);
}
}
5、Math类
import java.util.Scanner;
/*
Math: Math类包含执行基本数字运算的方法,如基本指数,对数,平方根和三角函数。
该类中没有构造方法,将来我们可以直接通过Math类名访问静态的成员
*/
public class MathDemo {
public static void main(String[] args) {
// System.out.println("圆周率:" + Math.PI);
// System.out.println(Math.max(19, 78)); // 底层是通过三目运算符实现的
//public static double random()
// System.out.println(Math.random()); // [0.0, 1.0) -> [0.0, 100.0) -> [1.0, 101.0) -> [1, 101)
//需求:随机生成一个1-100之间的整数
int number = (int) (Math.random() * 100 + 1);
// System.out.println(number);
//需求1:编写一个猜数字的小游戏
//需求2:编写一个猜数字的小游戏,但是只有3次机会
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
int i = 3;
System.out.println("您共有 " + i + " 次机会!");
while (i > 0) {
System.out.println("请输入要猜的数字:");
int n = sc.nextInt();
if (n > number) {
System.out.println("您猜大了,请往小的猜!");
} else if (n < number) {
System.out.println("您猜小了,请往大的猜!");
} else {
System.out.println("恭喜您,猜对了,数字为:" + number);
break;
}
i--;
if (i == 0) {
System.out.println("您的三次机会已经使用完了~!");
System.out.println("正确答案是:" + number);
break;
} else {
System.out.println("您还剩下 " + i + " 次机会!");
}
}
}
}
6、代码块
/*
代码块:在java程序中,使用{}括起来的代码,代码块
在不同的位置,以及使用不同的修饰词写的代码块,分为不同种类的代码块。
局部代码块:在方法中使用带括号括起来的代码段,整体称之为叫做局部代码块,主要作用是限定变量的作用域
构造代码块:写法和局部代码块的写法是一样的,但是构造代码块是写在类中方法外的位置
随着构造方法的调用而执行,执行顺序是 构造代码块->构造方法
静态代码块:写法上在前两种代码块的写法上,前面是使用static进行修饰,在类中方法外编写
是在程序运行之前,加载的时候执行,只会加载一次,静态代码块只会在程序运行之前有且仅执行一次!
同一个类中静态代码块之间的执行顺序是自上而下
静态代码块 -> 构造代码块 -> 构造方法
同步代码块【今天不说,放到后面多线程的时候讲解】
*/
public class CodeDemo1 {
CodeDemo1(){
System.out.println("这是无参的构造方法。。。。");
}
//静态代码块
static {
System.out.println("这是静态代码块1。。");
}
//构造代码块
{
System.out.println("这是构造代码块。。。");
}
//静态代码块
static {
System.out.println("这是静态代码块2。。。");
}
public static void main(String[] args) {
// {
// //局部代码块
// int a = 10;
// System.out.println(a);
// }
//
// {
// //局部代码块
// int a = 20;
// System.out.println(a);
// }
CodeDemo1 codeDemo1 = new CodeDemo1();
CodeDemo1 codeDemo2 = new CodeDemo1();
}
}
一个对象的内存图:
static静态区内存图:
创建对象成员变量初始化的过程: