1,Java面向对象之类和对象
1.1,面向过程和面向对象
1.1.1,面向过程
- 面向过程编程就是分析出解决问题的步骤。
- 然后使用函数把这些步骤一步步实现。
- 重心放在完成的每个过程中。
1.1.2,面向对象
- 构成问题事务分解成各个对象。
- 描述某个事物在整个解决问题的步骤中的行为。
1.1.3,面向过程和面向对象的区别
- 面向过程就是步骤,就是解决问题的按部就班。
- 面向对象关注的是解决问题所需要的对象。
- 面向过程就是自己办事,面向对象就是托人办事。
1.2,现实世界的面向对象
1.2.1,类和对象的关系
1.3,Java的类和对象之间的关系
1.3.1,Java的类
- 类可以看做一个模板,用于描述一类对象的行为和状态。
1.3.2,Java的类的描述
public class Person
{
String name;
int age;
int height;
void dance()
{
}
void sing()
{
}
}
1.3.3,Java的对象
张三 |
对象 |
姓名 |
万物皆对象 |
年龄 |
对象是具体的物体 |
身高 |
拥有属性 |
体重 |
拥有行为 |
唱歌 |
把多个零散的构建成一个整体 |
跳舞 |
具有唯一性 |
1.3.4,Java的类和创建对象
public class Person
{
public static void main(String[] args)
{
Person p = new Person();
}
}
public class Person
{
String name;
int age;
int height;
public static void main(String[] args)
{
Person p = new Person();
p.name = "华为鸿蒙";
p.age = 2;
p.height = 1024;
System.out.println("姓名:" + p.name + ",年龄:" + p.age + ",身高:" + p.height);
}
}
1.3.5,Java的对象与关键字
- new关键字表示创建一个对象。
- new关键字表示实例化对象。
- new关键字表示申请内存空间。
public class Person
{
public static void main(String[] args)
{
Person person = null;
}
}
class Person
{
}
public class Test
{
Person person = new Person();
}
栈内存 |
|
堆内存 |
person |
new–> |
age=0;name=null |
public class Person
{
String name;
int age;
public static void main(String[] args)
{
Person person = new Person();
person.name = "张三";
person.age = 20;
}
}
栈内存 |
|
堆内存 |
person |
new–> |
person.name=“张三”;person.age=20; |
1.3.6,Java在内存中创建多个对象
public class Person
{
String name;
int age;
public static void main(String[] args)
{
Person person1 = new Person();
person1.name = "张三";
person1.age = 20;
Person person2 = new Person();
person2.name = "李四";
person2.age = 20;
}
}
栈内存 |
|
堆内存 |
person1 |
new–> |
person1.name=“张三”;person1.age=20; |
person2 |
new–> |
person2.name=“李四”;person2.age=20; |
1.4,实例变量和静态变量
1.4.1,实例变量
- 声明在一个类中,但在方法、构造方法和语句块之外。
- 无static修饰。
- 数值型变量默认为0。
- 布尔型默认值为false。
- 引用类型默认值为null。
- 实例变量属于该类的对象,必须产生该类对象,才能调用实例变量。
- 实例变量的访问赋值
public class Person
{
String name;
int age;
int height;
public static void main(String[] args)
{
Person p = new Person();
p.name = "zhangsan";
p.age = 18;
p.height = 1024;
System.out.println("姓名:" + p.name + ",年龄:" + p.age + ",身高:" + p.height);
}
}
1.4.2,静态变量
- 独立于方法之外的变量,用static修饰,静态变量,也可以叫做类变量。
- static不能修饰局部变量。
public class Student
{
private String name;
private static String schoolName;
}
1.5,匿名构造函数和构造函数
1.5.1,构造函数
- Java构造函数,也叫构造方法,是Java中一种特殊的函数。
- 构造函数没有返回类型,函数名和类名保持一致。
- new对象产生后,就调用了对象的属性和方法。
- 作用:一般用来初始化成员属性和成员方法的。
- 格式:1,修饰符 类名(参数列表){} ;2,直接类名(参数列表){}
public class Employee
{
public Employee()
{
}
}
public class Employee
{
public Employee(String name)
{
}
}
public class Employee
{
public Employee(String name, int age)
{
return;
}
}
- 构造方法不是手动调用的,是对象被创建的时候JVM调用的。
- 如果一个类没有定义构造方法,JVM在编译的时候会给这个类默认添加一个无参数构造方法。
- 如果定义了构造方法,那么JVM不会再创建无参数构造方法。
- 创建对象的时候,有几个参数,就要有相应的构造方法,也是对应的要有几个参数。
- 构造函数可以调用构造函数。
public class Employee
{
String name;
int age;
public Employee()
{
name = "华为";
age = 2;
}
}
public class Student
{
String name;
int age;
public static void main(String[] args)
{
Student s = new Student();
}
}
public class Student
{
String name;
int age;
public Student(String name, int age)
{
}
public static void main(String[] args)
{
Student s1 = new Student("华为", 2);
}
}
1.5.2,匿名构造块
- 构造代码块的格式:{}
- 代码块的作用:对象统一初始化
- 对象创建之前都会执行这个代码块
public class Dept
{
{
System.out.println("这是匿名构造块");
}
public static void main(String[] args)
{
Dept dept = new Dept();
}
}
public static class Dept
{
{
System.out.println("这是匿名构造块");
}
public Dept(String name)
{
}
public static void main(String[] args)
{
Dept dept = new Dept("部门");
}
}
1.6,构造函数重载
1.6.1,重载概念
- 构造函数重载是多态的一个典型的特例
- 类中有多个构造函数,参数列表不同
- 重载构造函数来表达对象的多种初始化行为
- 构造函数重载 -> 相同的方法名(和类名一致) -> 参数列表不同 -> 实现的结果不同
public class Person
{
String name;
int age;
public Person()
{
}
public Person(String pname, int page)
{
name = pname;
age = page;
}
public static void main(String[] args)
{
Person p1 = new Person();
Person p2 = new Person("华为", 10);
}
}
1.7,方法定义和调用
1.7.1,方法的定义
- 方法是类或对象的行为特征的抽象
- Java中的方法不能独立存在,必须定义在类体中
- 方法定义没有先后顺序
- 方法的定义不能产生嵌套包含关系
- 方法定义中的返回值与传递的参数类型均为Java中定义的数据类型
- 在方法中可以进行返回值的处理,格式:return 返回数据类型; void 不返回数据类型
public class Person
{
public void eat()
{
System.out.println("这个eat方法是声明了void类型,void类型没有返回值");
}
public int getAge()
{
System.out.println("这个getAge方法是声明int类型,表示需要在方法的最后使用return返回具体的值");
return 20;
}
}
1.7.2,方法的调用
- 方法定义了,不会执行,如果想要执行,应进行方法调用
- 本类中的方法调用:方法名(参数列表)
- 外部类中的方法调用:调用类的对象.方法名(参数列表)
public class Person
{
public void eat()
{
System.out.println("这个eat方法是声明了void类型,void类型就是没有返回值");
}
public int getAge()
{
System.out.println("这个getAge()方法是声明了int类型,表示需要在方法的最后使用return返回具体的值");
return 20;
}
public static void main(String[] args)
{
Person p = new Person();
p.eat();
int age = p.getAge();
System.out.println("年龄是:" + age);
}
}
1.7.3,构造函数和普通方法的区别
名称 |
具体区别 |
函数名 |
1,构造函数是没有返回值类型的 |
|
2,普通函数是有返回值类型的,即使函数没有返回值,返回值类型也要写上void |
返回值类型 |
1,构造函数的函数名必须要与类名一致 |
|
2,普通函数的函数名只要符合标识符的命名规则即可 |
调用方式 |
1,构造函数是在创建对象的时候由JVM调用的 |
|
2,普通函数是由我们创建对象调用的 |
作用 |
1,构造函数的作用用于初始化一个对象 |
|
2,普通函数是用于描述一类事物的公开行为的 |
1.8,方法重载和编译时多态
1.8.1,方法的重载
- 一个类中多个方法名称相同
- 参数的列表不同
- 返回值类型无关
- 与修饰符无关
public class Employee
{
public void eat()
{
System.out.println("员工默认吃工作餐");
}
public void eat(String food)
{
System.out.println("在一些特定日子员工可以定制具体的食物,具体的食物是:" + food);
}
public static void main(String[] args)
{
Employee e = new Employee();
e.eat();
e.eat("北京烤鸭");
}
}
1.8.2,编译时多态
早期绑定
- 早期绑定就是指被调用的目标方法如果在编译期可知且运行期保持不变时,即可将这个方法所属的类型进行绑定
重载的方法是早期绑定完成
- 调用了一个重载的方法,在编译时根据参数列表就可以确定方法
1.9,面向对象的封装
1.9.1,封装概念
- 封装是指隐藏对象的属性和实现细节,仅对外提供公共访问方式
1.9.2,封装原则
- 将不需要对外提供的内容都隐藏起来
- 把属性都隐藏,提供公共方法对其访问
1.9.3,封装好处
1.9.4,从数据安全角度
- 没有封装,在外部类中可以直接访问修改数据,造成数据不安全
public class Employee
{
double salary;
}
public class Manager
{
public static void main(String[] args)
{
Employee emp = new Employee();
emp.salary = 0.0;
}
}
1.9.5,封装的控制和实现
public class Employee
{
private double salary;
}
public class Manager
{
public static void main(String[] args)
{
Employee e = new Employee();
}
}
public class Employee
{
private double salary;
public void setSalary(double newSalary)
{
if (newSalary >= 5000)
{
salary = newSalary;
} else
{
System.out.println("对不起,设置员工工资不符合员工最低工资标准");
}
}
public double getSalary()
{
return salary;
}
}
public class Manager
{
public static void main(String[] args)
{
Employee e = new Employee();
e.setSalary(6000);
}
}
1.9.6,该藏的藏,该露的露
- 我们程序设计要追求"高内聚,低耦合"
- 高内聚就是类的内部数据操作细节自己完成,不允许外部干涉
- 低耦合:仅暴露方法给外部使用
- 应禁止直接访问一个对象中数据的实际表示,而通过操作方法来访问,称为数据隐藏
2.0,this访问本类属性
- this代表当前对象的一个引用
- 所谓当前对象,指的是调用类中方法或属性的那个对象
- this只能在方法内部使用,表示对"调用方法的那个对象"的引用
- this.属性名:表示本对象自己的属性
public class Person
{
String name;
int age;
public Person(String name, int age)
{
this.name = name;
this.age = age;
}
public static void main(String[] args)
{
Person p1 = new Person("张三", 20);
Person p2 = new Person("李四", 22);
}
}
2.1,this调用方法
- this关键字调用类的重载构造函数
- this关键字必须位于构造函数的第一行
public class Person
{
String name;
int age;
public Person(ing age)
{
this.age = age;
}
public Person(String name)
{
this(1);
this.name = name;
}
public static void main(String[] args)
{
Person p1 = new Person("出生婴儿1");
Person p2 = new Person("出生婴儿2");
}
}
public class Student
{
public void eat()
{
System.out.println("同学先吃点东西");
}
public void talk()
{
this.eat();
System.out.println("同学吃完再说");
}
}
2.2,this关键字使用注意
- this不能用于静态方法和静态块
- main方法也是静态的,所以this也不能用于main方法
public class Person
{
String name;
int age;
public static void main(String[] args)
{
this.name = "华为";
this.age = 20;
}
}
2.3,static静态变量
- static变量也称作静态变量,也叫做类变量
- 静态变量被所有的对象所共享,在内存中只有一个副本
- 当且仅当在类初次加载时会被初始化
- 静态变量属于类
- 通过类名就可以调用静态变量
- 也可以通过对象名.静态变量调用
public class Student
{
private String name;
private static String schoolName;
private static int count;
public Student(String name)
{
this.name = name;
count++;
}
public void showStuInfo()
{
System.out.println("学生姓名是:" + this.name + ",学校名字是:" + Student.schoolName);
}
public static void main(String[] args)
{
Student.schoolName = "华为中学";
Student s1 = new Student("张三");
Student s2 = new Student("李四");
Student s3 = new Student("王五");
s1.showStuInfo();
s2.showStuInfo();
s3.showStuInfo();
System.out.println("学生数量是:" + Student.count);
}
}
学生类 |
学生对象 |
学生对象 |
姓名 |
张三 |
李四 |
年龄 |
18 |
19 |
学号 |
001 |
002 |
上课教室 |
301 |
302 |
public class Student
{
private String name;
private int age;
private int studentId;
private static String classRoom;
}
2.3.1,实例变量和静态变量区别
- 静态变量属于类,该类不生产对象,通过类名就可以调用静态变量。
- 实例变量属于该类的对象,必须产生该类对象,才能调用实例变量
- 静态变量随着类的加载存在于方法区中
- 实例变量随着对象的建立存在于堆内存中
- 静态变量在程序开始时创建,在程序结束时销毁
- 实例变量在对象创建的时候创建,在对象被销毁时销毁
2.4,静态方法
2.4.1,static修饰方法
- static修饰的方法叫静态方法,也叫类方法
- 静态方法中不能直接访问类的非静态成员变量和非静态成员方法
- 静态方法中不能使用this关键字
- 通过类名就可以调用静态方法
- 也可以通过对象名.静态方法名调用
public class Student
{
private String name;
private int age;
private int studentId;
private static String classRoom;
public static void showClassRoom()
{
System.out.println("自习教室是101");
}
public static void main(String[] args)
{
Student.showClassRoom();
}
}
2.5,静态块
- 静态代码块在类加载时执行,并且只执行一次
- 静态代码块在类中可以有多个
- 静态代码块中不能有this关键字
public class Emp
{
static
{
System.out.println("新员工");
}
static
{
System.out.println("上班要打卡");
System.out.println("下班要打卡");
}
}
2.5.1,静态块,匿名构造块,构造函数
package com.huawei.demo1;
class Student
{
int age;
String name;
boolean sex;
public Student()
{
age = 10;
name = "Huawei";
sex = false;
System.out.println("这是构造函数");
}
static
{
System.out.println("这是静态块");
}
{
System.out.println("这是一个匿名构造块");
}
}
public class Demo1
{
public static void main(String[] args)
{
Student s1 = new Student();
Student s2 = new Student();
Student s3 = new Student();
Student s4 = new Student();
}
}
2.6,类的生命周期
- Java一个类的生命周期
2.7,类的设计
2.7.1,学生类设计
设计一个学生类 |
1,Student类中包含姓名、成绩两个属性 |
2,分别给这两个属性定义两个方法,一个方法用于设置值,另一个方法用于获取值 |
3,Student类中定义一个无参数构造方法和一个接收两个参数的构造方法,两个参数分别为姓名和成绩属性赋值 |
4,在测试类中创建两个Student对象,一个使用无参数构造方法,然后调用方法给姓名和成绩赋值,另一个使用有参数构造方法,在构造方法中给姓名和成绩赋值 |
2.7.2,学生类实现
class Student
{
private String name;
private int grade;
public Student()
{
}
public Student(String name, int grade)
{
this.name = name;
this.grade = grade;
System.out.println("我叫:" + name + ",成绩为:" + grade);
}
public String getName()
{
return name;
}
public int getGrade()
{
return grade;
}
public void setName(String name)
{
this.name = name;
}
public void setGrade(int grade)
{
this.grade = grade;
}
}
public class StudentExample
{
public static void main(String[] args)
{
Student s1 = new Student();
Student s2 = new Student("Huawei", 18);
s1.setName("Huawei1");
s1.setGrade(100);
System.out.println("姓名:" + s1.getName() + ",成绩:" + s1.getGrade());
}
}
2.7.3,教师类设计
设计一个教师类 |
1,定义Teacher类,定义两个成员变量name,sid,学校名称schoolName静态变量 |
2,定义Teacher类构造函数,对name,sid初始化赋值,并提供get/set属性的方法 |
3,编写测试类TeacherTest,创建Teacher类对象,使用set属性方法设置值,get属性方法获取值 |
2.7.4,教师类实现
class Teacher
{
private String name;
private int sid;
public static String schoolName;
static
{
schoolName = "Huawei School";
}
public Teacher()
{
}
public Teacher(String name, int sid)
{
this.name = name;
this.sid = sid;
}
public String getName()
{
return name;
}
public int getSid()
{
return sid;
}
public void setName(String name)
{
this.name = name;
}
public void setSid(int sid)
{
this.sid = sid;
}
}
public class TeacherTest
{
public static void main(String[] args)
{
Teacher t = new Teacher();
t.setName("huawei");
t.setSid(100);
System.out.println("老师名字:" + t.getName() + ",老师编号:" + t.getSid()
+ "老师所在学校:" + Teacher.schoolName);
}
}
2.7.5,课程类设计
设计一个课程类 |
1,定义课程类Course,有课程编号cno,课程名称cname,任课老师对象Teacher |
2,课程类Course的构造函数,完成对课程编号,课程名称,任课老师的初始化 |
3,定义实例方法输出课程信息和关联的任课老师信息 |
2.7.6,课程类实现
public class Course
{
private String cno;
private String cname;
private Teacher teacher;
public Course(String cno, String cname, Teacher teacher)
{
this.cno = cno;
this.cname = cname;
this.teacher = teacher;
}
public void queryCourseInfo()
{
System.out.println("课程名称:" + this.cname + ",任课老师是:" + teacher.getName());
}
public static void main(String[] args)
{
Teacher t = new Teacher("Huawei teacher", 1024);
Course course = new Course("10", "java", t);
course.queryCourseInfo();
}
}
2.7.7,成绩类设计
设计一个成绩类 |
1,设计成绩类Score,有学生对象s,课程对象c,和分数score |
2,成绩类的构造函数,完成对学生对象,课程对象,分数的初始化 |
3,通过实例方法输出学生所学课程的成绩,同时输出任课老师的信息 |
2.7.8,成绩类实现
public class Score
{
private Student s;
private Course c;
private int score;
public Score(Student s, Course c, int score)
{
this.c = c;
}
public void showStudentScoreInfo()
{
System.out.println("学生姓名是:" + s.getSname() + ",课程名称:" + c.getName() +
",任课老师姓名:" + c.getTeacher().getName());
}
public static void main(String[] args)
{
Student s = new Student("01", "huawei");
Teacher t = new Teacher("huaweiteacher", 1002);
Course c = new Course("10", "java");
Score s = new Score(s, c, t);
s.showStudentScoreInfo();
}
}
2.8,Java方法参数
2.8.1,方法参数的类型(基本类型和引用类型)
- 在Java方法中参数列表有两种类型的参数,基本类型和引用类型。
- 参数类型是基本数据类型,那么传过来的就是这个参数的一个副本。
- 参数类型是引用类型,那么传过来的就是这个引用参数的副本,这个副本存放的是参数的地址。
public class Test1
{
int a = 5;
int b = 6;
public void change(int a, int b)
{
a = 20;
b = 30;
System.out.println("change方法里,a的值为:" + a + ",b的值为:" + b);
}
public static void main(String[] args)
{
Test1 t = new Test1();
t.change(t.a, t.b);
System.out.println();
System.out.println("交换结束后,a的值为:" + t.a + ",b的值为:" + t.b);
}
}
public class Test2
{
int a = 5;
int b = 6;
public void change(Test2 t)
{
t.a = 20;
t.b = 30;
System.out.println("change方法里,a的值为:" + a + ",b的值为:" + b);
}
public static void main(String[] args)
{
Test2 t = new Test2();
t.change(t);
System.out.println();
System.out.println("交换结束后,a的值为:" + t.a + ",b的值为:" + t.b);
}
}
2.8.2,Java的可变参数列表
public class Test
{
public void add(int... a)
{
for (int i = 0; i < a.length; i++)
{
System.out.print(a[i] + " ");
}
}
public static void main(String[] args)
{
Test t = new Test();
t.add();
t.add(1);
t.add(1, 2, 3, 4);
}
}
2.8.3,Java参数传递基本数据类型和引用数据类型区别
说明 |
基本数据类型 |
引用数据类型 |
根本 |
会创建副本 |
不会创建副本 |
所以 |
函数中无法改变原始对象 |
函数中可以改变原始对象 |
2.9,方法参数实战
public class Test
{
private int a;
private boolean flag;
public void change(int a)
{
a = 20;
}
public void change(int a, boolean flag)
{
this.a = 30;
}
public static void main(String[] args)
{
Test t = new Test();
t.change(t.a);
System.out.println("1,t.a的值是:" + t.a);
t.change(t.a, t.flag);
System.out.println("2,t.a的值是:" + t.a);
}
}
public class Test1
{
private int a;
private boolean flag;
public void change(Test1 t)
{
t.a = 20;
}
public void change(Test1 t, boolean flag)
{
Test1 t1 = new Test1();
t = t1;
t.a = 40;
}
public static void main(String[] args)
{
Test1 t = new Test1();
t.change(t);
System.out.println("1,t.a的值为:" + t.a);
t.change(t, t.flag);
System.out.println("2,t.a的值为:" + t.a);
}
}
评论(0)