面向过程(PO):
一种非常古老的编程思想,顾名思义就是该思想是站在过程的角度去思考问题,强调的是功能的行为,指的是先完成什么功能,后完成什么功能,而每一个功能都使用函数(方法)把这些步骤一步一步的进行实现,需要使用的时候就依次调用对应的功能就可以了。
说人话:
提倡和注重的是每一个功能都来使用方法进行操作,而继续使用某一功能的时候就继续挨着方法就可以了;面向过程的最大的问题在于随着系统的膨胀,面向过程根本没有办法应付,最终很有可能导致系统崩溃,为了解决这样的一个问题,有人提出了面向对象的编程思想。
面向对象(OO):
是一种基于面向过程的编程,顾名思义,该思想是站在面向过程的基础上去改善为面向对象,原则是将多个功能合理的放到到一个对象当中,然后指挥对象来做事。强调的是具备某些功能的对象。
面向对象的优势和特点:
面向对象是一种更加符合我们思想的思维方式,稳定性好,可重用性强,易于开发大型架构的软件,具备非常良好的可维护性
面向对象的三大特征:
封装:
封装是指将对象的细节和实现隐藏起来,然后通过公共的访问方式对外提供对象的功能
继承:
是实现面向对象代码复用的重要手段通过子类继承父类的方法,子类可以是一种特殊父类,可以继续扩展也可以反复的使用父类的方法
多态:
是可以直接把子类对象赋值给父类对象,但运行的时候依然表现出子类的行为特征,这也就意味着同一类型
的对象在运行的时候可以表现出不同的姿态(行为特征)
注意:
千万不要误解为面向对象就一定会优于面向过程,面向对象本质上还是基于面向过程,如果你的项目非常非常小 那么面向过程的开发能力甚至优于面向对象
面向对象和面向过程的举例:
买电脑:
面向过程:想清楚需要什么电脑–>百脑汇–>对比品牌–>确定参数–>讨价还价–>电脑买回家
面向对象:想清楚需要什么电脑–>交给超哥(给钱)–>超哥买回来
面向对象的开发、特征
面向对象开发:就是不断的创建对象,使用对象,指挥对象做事情。
面向对象设计:其实就是在管理和维护对象之间的关系。
类和对象的关系:
现实世界当中,怎么去描述一个美女
姓名、年龄、性别…
打麻将、学Java、抛媚眼
如何去描述一个事物?
属性:姓名、年龄、性别…
行为:打麻将、学Java、抛媚眼
我们学习Java语言,是不是就是为了模拟现实的一些事物,但是我们学习的Java,最基本的单位是:类,所以我们应该将现实的事物通过类来表示出来,由此,我们需要了解现实事物和类的对应的关系
事物 | 类 |
---|---|
属性 | 成员变量 |
行为 | 成员方法 |
类:类是一组相关的属性和行为的集合,是一个抽象的概念
对象:是该类事物具体表现的存在,也是具体存在的个体
定义一个类,其实就是定义他的成员变量和成员方法,把现实的事物转换为类
成员变量:和之前的变量的定义的格式是一样的,但是位置不同,在类中方法外
成员方法:和之前的方法的定义格式是一样的,只不过我们想去掉static
public class Student {
//定义变量
//姓名
String name;
//年龄
int age;
//性别
char sex;
//成员方法
//学习的方法
public void study() {
System.out.println("你们爱学习");
}
//吃饭的方法
public void eat() {
System.out.println("我们爱吃饭");
}
//睡觉的方法
public void sleep() {
System.out.println("睡觉");
}
}
如何使用对象?
创建对象
如何创建对象?
格式:类名 对象名 = new 类型();
如何使用对象的成员变量?
对象名.变量名;
如何使用对象的成员方法?
对象名.方法名;
打印对象:
默认输出的:面向对象概述.Student@15db9742,对象类型@十六进制的hashCode
和数组是一样的,我不能直接看到值 具体的等我们学到Object类时候再讲
对象的比较:
每一次new出来的东西,都会有新的地址值 新的空间
对于对象来说,而"==",比较的是地址值是否相同,而不是内容是否相同
对象的生命周期:
从new出来的时候开辟空间,到垃圾回收器回收的时候结束生命
垃圾:内存当中的某一块空间没有被一个栈内存引用的时候,才是垃圾
垃圾产生时,不一定会运行GC,GC是自动调度 我们没有办法进行干预
成员变量和局部变量的区别?
在类中的位置不同
成员变量 类中方法外
局部变量 方法内或者方法声明上
在内存中的位置不同
成员变量 堆内存
局部变量 栈内存
生命周期不同
成员变量 随着对象的存在而存在,随着对象的消失而消失
局部变量 随着方法的调用而存在,随着方法的调用完毕而消失
初始化值不同
成员变量 有默认的初始化值
局部变量 没有默认的初始化值,必须先定义,赋值,才能使用。
注意事项:
局部变量的命名可以和成员变量的命名一致,但是调用的原则是就近原则
成员变量和局部变量案例:
class Variable{
int num;
public void show() {
int num2 = 20;
//int num2;//num2没有进行初始化
System.out.println(num2);
// int num = 100;
System.out.println(num);
System.out.println(num);
}
}
//测试类
public class VariableDemo {
public static void main(String[] args) {
Variable v = new Variable();
System.out.println(v.num);//0
v.show();//20 100
}
}
Java的封装的思想案例:
class Student{
//姓名
private String name;
//年龄
private int age;
public void setAge(int a) {
if(a < 0 || a > 120) {
System.out.println("您的年龄想清楚再来。");
}else {
age = a;
}
}
public void setName(String n) {
name = n;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
//显示姓名和年龄的方法
private void show() {
System.out.println("姓名:"+name);
System.out.println("年龄:"+age);
}
}
public class StudentDemo {
public static void main(String[] args) {
//创建学生对象
Student s = new Student();
// s.show();//null 0
System.out.println("-------------------------");
//给成员变量赋值
// s.name = "超哥";
// s.age = 18;
// s.show();
s.setAge(18);
s.setName("超哥");
int age = s.getAge();
System.out.println(age+"---"+s.getName());
}
}
分析案例:
成员变量:name age
成员方法:show()
我们在使用这个案例的时候发现了一些问题:我们通过成员变量进行赋值的时候,可以赋予一些非法的数据,这是不合理。
怎么解决?应该是这样子,我们在赋值之前就应该先做好数据的校验,这个校验应该放在哪个地方合适?StudentDemo是一个测试类,测试类一般只用于数据的测试和方法的调用,所以我们应该放在后台,也就Student类当中,我们如何判断?在赋值之前,我们写好一个方法就可以,虽然说,我们写了一个数据校验的方法,但是开发者或者用户完全可以不使用,从而继续使用带有漏洞的成员变量,我们有没有一种办法,可以要求别人只能使用我的某个方法?
可以,针对这种问题,Java提供了一个关键字 “private”,“private”:私有的,可以修饰成员变量和成员方法,其实,这种情况也慢慢引入了Java的封装的思想
构造方法
给对象进行数据初始化
格式:
a.方法名和类名一致
b.没有返回值类型,甚至连void也没有
c.没有具体的返回值
案例:
class Student{
private String name;
private int age;
public Student() {
name = "超哥";
System.out.println("我是构造");
}
}
public class ConstructDemo {
public static void main(String[] args) {
Student student = new Student();
System.out.println(student);
}
}
在我们之前的所有代码当中,其实都有使用构造方法,但是我们从来没自己去定义过构造
构造的注意事项:
a.如果我们没有给出构造方法,系统将自动提供一个默认的无参构造
b.如果我们手动给出了任意构造方法,系统将不再提供默认的无参构造
注意:如果这个时候还想继续使用无参构造,就必须自己手动给出,而且建议永远提供无参构造
class Student01{
private String name;
private int age;
//构造方法的重载
public Student01(String name) {
this.name = "超哥";
System.out.println("我是构造");
}
public Student01(String name,int age) {
this.name = name;
this.age = age;
}
private Student01() {//如果构造私有化,则代表外界无法使用该对象
}
匿名对象
就是没有名字的对象
匿名对象使用的场景:
a.调用方法,仅仅只使用一次的时候进行使用
注意:如果使用多次,不适合 因为会产生多个对象,而且是垃圾对象,那么,我们还要使用匿名对象吗?有什么好处吗?
有,匿名对象使用完毕之后就是垃圾,垃圾可以被垃圾回收器进行回收
b.匿名对象可以作为实际参数进行传递
案例:
class Student{
public void show() {
System.out.println("超哥爱学习");
}
}
class StudentDemo{
public void method(Student s) {
s.show();
}
}
public class NoNameDemo {
public static void main(String[] args) {
//带名字的调用
Student s = new Student();
s.show();
s.show();
System.out.println("--------------------");
new Student().show();
new Student().show(); //其实这里是一个新的内存地址
//作为形式参数传递的调用
StudentDemo sd = new StudentDemo();
sd.method(s);
sd.method(new Student());
//再来一个 奇葩
new StudentDemo().method(new Student());
}
}
this
当前类的引用,简单的说法就是他是一个类的具体对象
注意:谁调用,this就代表该对象
this使用的常用场景?
解决的是局部变量隐藏成员变量的问题
案例:
class Student{
//姓名
private String name;
//年龄
private int age;
//获取名字
public String getName() {
return name;
}
//设置名字
public void setName(String name) {
// name = name;//变量使用的是就近原则
//Student.name 这种做法也可以获取一个类的成员变量 但是不是现在讲
//所以我们只能够通过对象名来调用它
// student.name
//有一种东西,能够代表当前对象,这个东西就是this关键字
this.name = name;
}
//获取年龄
public int getAge() {
return age;
}
//设置年龄
public void setAge(int i) {
age = i;
}
}
public class StudentDemo {
public static void main(String[] args) {
//创建学生对象
Student student = new Student();
student.setAge(18);
student.setName("超哥");
System.out.println(student.getName()+"--"+student.getAge());
}
}