1. 对象的概念及面向对象的三个基本特征
面向对象的三大核心特性
面向对象开发模式更有利于人们开拓思维,在具体的开发过程中便于程序的划分,方便程序员分工合作,提高开发效率。面向对象程序设计有以下优点。
- 可重用性:它是面向对象软件开发的核心思路,提高了开发效率。面向对象程序设计的抽象、继承、封装和多态四大特点都围绕这个核心。
- 可扩展性:它使面向对象设计脱离了基于模块的设计,便于软件的修改。
- 可管理性:能够将功能与数据结合,方便管理。
该开发模式之所以使程序设计更加完善和强大,主要是因为面向对象具有继承、封装和多态 3 个核心特性。
继承性
如同生活中的子女继承父母拥有的所有财产,程序中的继承性是指子类拥有父类数据结构的方法和机制,这是类之间的一种关系;继承只能是单继承。
例如定义一个语文老师类和数学老师类,如果不采用继承方式,那么两个类中需要定义的属性和方法.
语文老师类和数学老师类中的许多属性和方法相同,这些相同的属性和方法可以提取出来放在一个父类中,这个父类用于被语文老师类和数学老师类继承。当然父类还可以继承别的类,
学校主要人员是一个大的类别,老师和学生是学校主要人员的两个子类,而老师又可以分为语文老师和数学老师两个子类,学生也可以分为班长和组长两个子类。
使用这种层次形的分类方式,是为了将多个类的通用属性和方法提取出来,放在它们的父类中,然后只需要在子类中各自定义自己独有的属性和方法,并以继承的形式在父类中获取它们的通用属性和方法即可。
封装性
封装是将代码及其处理的数据绑定在一起的一种编程机制,该机制保证了程序和数据都不受外部干扰且不被误用。封装的目的在于保护信息,使用它的主要优点如下。
- 保护类中的信息,它可以阻止在外部定义的代码随意访问内部代码和数据。
- 隐藏细节信息,一些不需要程序员修改和使用的信息,比如取款机中的键盘,用户只需要知道按哪个键实现什么操作就可以,至于它内部是如何运行的,用户不需要知道。
- 有助于建立各个系统之间的松耦合关系,提高系统的独立性。当一个系统的实现方式发生变化时,只要它的接口不变,就不会影响其他系统的使用。例如 U 盘,不管里面的存储方式怎么改变,只要 U 盘上的 USB 接口不变,就不会影响用户的正常操作。
- 提高软件的复用率,降低成本。每个系统都是一个相对独立的整体,可以在不同的环境中得到使用。例如,一个 U 盘可以在多台电脑上使用。
Java 语言的基本封装单位是类。由于类的用途是封装复杂性,所以类的内部有隐藏实现复杂性的机制。Java 提供了私有和公有的访问模式,类的公有接口代表外部的用户应该知道或可以知道的每件东西,私有的方法数据只能通过该类的成员代码来访问,这就可以确保不会发生不希望的事情。
多态性
面向对象的多态性,即“一个接口,多个方法”。多态性体现在父类中定义的属性和方法被子类继承后,可以具有不同的属性或表现方式。多态性允许一个接口被多个同类使用,弥补了单继承的不足。
2. Java认识类和对象
类的定义
[访问权限修饰符] class 类名 {
属性/ 成员变量/ 字段
行为/ 成员方法
}
类的理解:
1.类是用来描述现实事物的,是Java语言的最基本单位
2.类是抽象的,是由多个对象抽象想象的部分而来
3.类可以理解为一个模板,数属性和行为的集合,可以通过类的模板创建具体的对象
4.Java使用class来描述一个类
5.类的本质用来组织代码(方法归类),封装数据的(理解提高成员变量的安全性)。
对象的理解:
1.对象是客观存在的,万事万物皆是对象
2.对象是在类的基础上创建的
3.对象又称为 实例/引用/变量/对象
如何创建一个对象?
格式: 类名 对象名 = new 类名();
如何访问一个对象?
访问成员
对象.成员变量
对象.成员方法
定义一个类的步骤
1、定义类名
2、编写类的属性
3、编写类的方法
4、创建对象
5、通过对象访问成员
匿名对象
概念: 没有名字的对象,本质还是一个对象
匿名对象的特点:
1.既然是对象,同样可以访问成员
2.匿名对象只能够使用一次,如果需要使用多次,必须使用变量接收
3.匿名对象一旦使用一次完毕,立刻成为垃圾对象,等待垃圾回收期在空闲的时候回收,节约内存资源
4.匿名对象在Java里一般用于访问一次的情况,简化代码,在Android里节约内存资源
1 public class OOPDemo04 {
2 @SuppressWarnings("resource")
3 public static void main(String[] args) {
4 Student s1 = new Student();
5
6 // new Student();
7 //
8 // System.out.println(new Student().name);
9 //
10 // new Student().print99MulTable();
11
12 new Student().name = "隔壁老王";
13 System.out.println(new Student().name); // null
14
15 String line = new Scanner(System.in).next();
16 System.out.println(line);
17
18 new Test().method(new Student());
19 }
20 }
21
22 class Test {
23 public void method(Student s) {
24 System.out.println(s.name);
25 }
26 }
27
28 结果 null
3. Java类的定义及定义类时可用的关键字
在 Java 中定义一个类,需要使用 class 关键字、一个自定义的类名和一对表示程序体的大括号。完整语法如下:
1 [public][abstract|final]class<class_name>[extends<class_name>]
2 [implements<interface_name>]
3 {
4 //定义属性部分
5 <property_type><property1>;
6 <property_type><property2>;
7 <property_type><property3>;
8 …
9 //定义方法部分
10 function1();
11 function2();
12 function3();
13 …
14 }
上述语法中各关键字的描述如下。
public
:表示“共有”的意思。如果使用 public 修饰,则可以被其他类和程序访问。每个 Java 程序的主类都必须是 public 类,作为公共工具供其他类和程序使用的类应定义为 public 类。abstract
:如果类被 abstract 修饰,则该类为抽象类,抽象类不能被实例化,但抽象类中可以有抽象方法(使用 abstract 修饰的方法)和具体方法(没有使用 abstract 修饰的方法)。继承该抽象类的所有子类都必须实现该抽象 类中的所有抽象方法(除非子类也是 抽象类)。final
:如果类被 final 修饰,则不允许被继承。class
:声明类的关键字。class_name
:类的名称。extends
:表示继承其他类。implements
:表示实现某些接口。property_type
:表示成员变量的类型。property
:表示成员变量名称。function()
:表示成员方法名称。
4. 形参和实参及成员变量和局部变量
1、形参和实参
关于方法的参数,经常会提到形参与实参,形参是定义方法时参数列表中出现的参数,实参是调用方法时为方法传递的参数。
1 public int returnMin(int m,int n)
2 {
3 return Math.min(m,n); //m和n是形参
4 }
5 public static void main(String[] args)
6 {
7 int x=50;
8 int y=100;
9 Test t=new Test();
10 int i=t.returnMin(x,y); //x和y是实参
11 System.out.println(i);
12 }
2、方法的形参和实参具有以下特点:
- 形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只有在方法内部有效,方法调用结束返回主调 方法后则不能再使用该形参变量。
- 实参可以是常量、变量、表达式、方法等,无论实参是何种类型的量,在进行方法调用时,它们都必须具有确定的值,以便把这些值传送给形参。因此应预先用赋值、输入等办法使实参获得确定值。
- 实参和形参在数量、类型和顺序上应严格一致,否则会发生“类型不匹配” 的错误。
- 方法调用中发生的数据传送是单向的,即只能把实参的值传送绐形参,而不能把形参的值反向地传送给实参。因此在方法调用过程中,形参的值发生改变,而实参中的值不会变化。
3、在调用成员方法时应注意以下 4 点:
- 对无参成员方法来说,是没有实际参数列表的(即没有 paramList),但方法名后的括号不能省略。
- 对带参数的成员方法来说,实参的个数、顺序以及它们的数据类型必须与形式参数的个数、顺序以及它们的数据类型保持一致,各个实参间用逗号分隔。实参名与形参名可以相同,也可以不同。
- 实参也可以是表达式,此时一定要注意使表达式的数据类型与形参的数据类型相同,或者使表达式的类型按 Java 类型转换规则达到形参指明的数据类型。
- 实参变量对形参变量的数据传递是“值传递”,即只能由实参传递给形参,而不能由形参传递给实参。程序中执行到调用成员方法时,Java 把实参值复制到一个临时的存储区(栈)中,形参的任何修改都在栈中进行,当退出该成员方法时,Java 自动清除栈中的内容。
4、方法体中的局部变量
在方法体内可以定义本方法所使用的变量,这种变量是局部变量。它的生存期与作用域是在本方法内,也就是说,局部变量只能在本方法内有效或可见,离开本方法则这些变量将被自动释放。
在方法体内定义变量时,变量前不能加修饰符。局部变量在使用前必须明确赋值,否则编译时会出错。另外,在一个方法内部,可以在复合语句中定义变量,这些变量只在复合语句中有效。
5、成员变量和局部变量的区别
1.定义的位置不同
成员变量: 类体以内,方法体以外
局部变量: 方法的声明上,或者方法体内
2.在内存的位置不一样
成员变量: 在堆区分配内存
局部变量: 在栈区分配内存
3.初始化值不一样
成员变量: 系统赋予初始值
byte short int long 0
float double 0.0
boolean false
char u0000
引用类型 null
局部变量: 方法的声明上,或者方法体内
没有默认值,必须先声明再赋值再使用
4.变量的生命周期不一样
生命周期: 变量从开始创建到销毁的全过程
成员变量: 随着对象的创建而创建,随着垃圾回收器回收对象的时候销毁
局部变量: 随着方法的调用而创建,随着方法调用结束而销毁
5.当成员变量和局部变量重名的时候,局部变量优先,就近原则
如果希望访问成员变量,需要使用this关键字
5.Java方法:Java方法的声明和调用
构造方法
为什么需要学习构造方法?
1.假设一个类中有100个属性,一个一个set很麻烦
构造方法: 构造方法本身就是一个特殊的方法而已
1.能够快速初始化成员变量的值
2.能够为对象分配内存空间 + new
构造方法的格式:
1 [访问权限修饰符] 方法名(参数列表) {
2 方法体;
3 // return 值;
4 return;
5 }
构造方法的特点:
1.构造方法没有返回值,连void都没有
2.构造方法也是方法,存在方法重载
3.构造方法是用来给成员快速初始化的
4.构造方法方法名必须和类名保持一致
构造方法的注意事项:
1.如果我们没有书写构造方法,系统会帮我们书写一个无参构造方法
2.如果你一旦书写了一个带参构造方法,就会覆盖系统的无参构造方法
3.养成一个好习惯: 每次书写一个bean的时候,都写上无参构造方法
好处:
1.无参构造方法能够初始化默认成员的值
2.反射中调用的就是无参构造方法,很多框架中都会利用反射技术创建对象,反射大部分都是依赖无参构造方法
类的组成
class 类 {
成员变量
构造方法
构造方法重载
成员方法
普通方法
读写方法 (get/set方法)
}
1 public class ConstructorDemo01 {
2 public static void main(String[] args) {
3 Student s = new Student();
4 s.setName("张三");
5 s.setAge(18);
6 s.show();
7
8 Student s2 = new Student("李四", 20, "男");
9 s2.show();
10
11 }
12 }
13
14 class Student {
15 private String name;
16 private int age;
17 private String gender;
18
19 public Student() {
20 }
21
22 public Student(String name, int age) {
23 this.name = name;
24 this.age = age;
25 }
26
27 public Student(String name, int age, String gender) {
28 this.name = name;
29 this.age = age;
30 this.gender = gender;
31 }
32
33 public String getName() {
34 return name;
35 }
36 public void setName(String name) {
37 this.name = name;
38 }
39 public int getAge() {
40 return age;
41 }
42 public void setAge(int age) {
43 this.age = age;
44 }
45
46 public String getGender() {
47 return gender;
48 }
49
50 public void setGender(String gender) {
51 this.gender = gender;
52 }
53
54 public void show() {
55 System.out.println("Student [name=" + name + ", age=" + age + ", gender=" + gender + "]");
56 }
57
58
59
60 }
Student [name=张三, age=18, gender=null]
Student [name=李四, age=20, gender=男]