Java面向对象(基础总结)
面向对象是一种编程思想。
- 面向对象的三大基本特征:
- 封装
- 继承
- 多态
- 面向对象的编程思想就是把事物看作一个整体,从事物的特征(属性)和行为(方法)两个方面进行描述。
- 面向对象的过程就是找对象、建立对象、使用对象、维护对象的关系的过程
面向过程和面向对象
面向过程 | 面向对象 | |
---|---|---|
设计思路 | 自顶向下、层次化、分解 | 自底向上、对象化、综合 |
程序单元 | 函数模块 | 对象 |
设计方法 | 程序=算法+数据结构 | 程序=对象=数据+方法 |
优点 | 相互独立,代码共享,性能相对较高 | 接近人的思维方式, 使用灵活,易维护、易复用、易扩展 |
缺点 | 修改、维护困难 | 性能相对较低 |
- 面向对象是基于面向过程的
- 面向对象能让复杂的问题简单化,程序员不需要了解具体的实现过程,只需要指挥对象去实现功能(从执行者变成指挥者)。
举例:
- 洗衣服:
- 使用面向过程思考:放入衣服 -> 打开洗衣机 -> 洗衣服 -> 关闭洗衣机
- 使用面向对象思考:洗衣服我们操作了洗衣机这个对象,所以只要给洗衣机这个对象增加这些功能,就可以实现洗衣服操作。放入衣服 -> 洗衣机:打开、洗衣服、关闭
- 面向过程:强调步骤;面向对象:强调对象。
面向对象的三大核心特性:
- 可重用性:代码重复使用,减少代码量,提高开发效率。面向对象的三大基本特征(继承、封装和多态)都围绕这个核心。
- 可扩展性:指新的功能可以很容易地加入到系统中来,便于软件的修改。
- 客观理性:能够将功能与数据结合,方便管理。
抽象
所谓的抽象,就是把同一类事物中共有的特征(属性)和行为(功能、方法)进行抽取,归纳,总结。
抽象的过程其实就是面向对象编程的核心思想
类
类:用来描述一类具有相同特征(属性)和相同行为(方法)的对象。(可以比喻为模板)
-
Java中用class关键字来描述类
- 成员属性(变量):对应的就是事物的属性
- 成员方法:对象事物的行为
-
类的定义:
public class 类名{ //成员变量 //成员方法 }
-
定义类:就是定义类的成员,包括成员变量和成员方法
-
类的成员:
- 成员变量:和之前定义的变量几乎时一样的,只不过位置发生了改变,成员变量位于类中,任何方法之外。
- 成员方法:和之前定义的方法几乎是一样的,只不过把static关键字去掉
类和对象的关系:
- 类是对象的抽象
- 对象是类的实例化
对象
对象(Object)是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位。
它们是有形的,如一个人、一件物品;也可以是无形的,如一个计划、一次交易。(万事万物,皆对象)
-
创建对象
类名 对象名 = new 类名();
-
使用对象:
调用成员变量:
对象名.成员变量;
调用成员方法:
对象名.方法名(参数列表);
-
成员变量(属性)都有默认值,所以在声明成员变量时,可以不用初始化(默认值和数据类型有关:)
数据类型 默认值 byte 0 short 0 int 0 long 0 float 0.0 double 0.0 boolean false char 空字符 引用类型 null
全局变量(成员变量)
- 定义在方法的外部,类的内部。使用范围是整个类
- 不需要初始值
- 存储在堆内存中(对象存在时才在存在)
局部变量
(方法中的变量)
- 定义在方法的内部或者某一个语句块的内部,适用范围仅限于方法内或者语句块内
- 必须有初始值
- 存储在栈内存中
成员方法
-
语法:
访问修饰符 返回值类型 方法名称(参数列表){ 方法体 }
- 访问修饰符:public
- 返回值类型由返回值决定
-
成员变量可以直接在成员方法中使用,但是main方法中如果调用成员变量和方法必须通过对象.属性名\方法名(参数列表)的形式来调用
-
成员方法之间的调用,直接写方法名(参数列表)即可
构造方法
对象一建立就会调用构造方法,可以创建对象,给成员变量(属性)初始化。
- 方法名和类名相同
- 没有返回值和void,没有return
- 不能被static等关键字修饰
- 可以方法重载(定义多个参数列表不同的构造方法)
- 当一个类中没有写构造方法时,系统会默认给该类一个默认的无参构造方法。当自己定义构造方法后默认的构造方法就不存在了。(自己定义有参的构造方法后,如果还想使用无参的构造方法,就要自己再添加一个无参的构造方法)
public class Animal {
String name;
int age;
//构造方法
public Animal(){
System.out.println("------无参的构造方法------");
name = "动物";
age = 0;
}
public Animal(String name,int age){
System.out.println("------有参的构造方法------");
this.name = name;
this.age = age;
}
public static void main(String[] args) {
//创建对象
Animal a1 = new Animal();
System.out.println(a1.name+","+a1.age);
Animal a2 = new Animal("兔子",2);
System.out.println(a2.name+","+a2.age);
}
}
this关键字
this代表它所在方法所属对象的引用。哪个对象调用的this所在的方法,this就代表哪个对象。
-
在没有static关键字修饰的方法中使用
-
this关键的字用来区分成员变量和局部变量同名的情况:
public class Student{ //成员变量 String name; int age; int classNum; public Student(String name,int age,int classNum){ //s1调用了构造方法,所以这里的this代表s1对象 this.name = name; //成员变量name=局部变量name this.age = age; this.classNum = classNum; } public static void main(String[] args){ Student s1 = new Student("张三",18,1); System.out.println(s1.name);//打印 张三 } }
-
this关键字在构造方法中的第一行以 this(参数列表) 的形式出现时,就表示当前构造方法调用了该类中其他的构造方法(于参数列表相匹配的构造方法):
public class Test1 { public Test1(){ this("张三",18); } public Test1(String name,int age){ System.out.println("姓名:"+name+",年龄:"+age); } public static void main(String[] args) { Test1 test1 = new Test1(); } }
封装
封装是将代码及其处理的数据绑定在一起的一种编程机制,该机制保证了程序和数据都不受外部干扰且不被误用。
- 封装的目的在于保护信息,保证数据的安全性
- 封装包括两个方面:属性的封装和方法的封装
- Java 提供了私有和公有的访问模式,类的公有接口代表外部的用户应该知道或可以知道的每件东西,私有的方法数据只能通过该类的成员代码来访问, 封装不是绝对的封装,如果想要访问封装起来的数据,可以通过指定的入口即可
- 属性和方法的封装两者时相辅相成、密不可分的
继承
程序中的继承性是指子类拥有父类的全部特征和行为,这是类之间的一种关系。
- 继承的特点:
- 继承要有一定的层次结构,而且还要具备一定的可传递性
- 子类继承了父类的所有属性和方法,但是不包括私有属性(private)和构造方法
- 子类继承父类的属性和方法同时也可以有自己的属性和方法。
- Java 只支持单继承。 也就是说一个子类只能有一个父类,父类可以有多个子类
- 继承可以减少重复代码、提高了复用性和维护性
- 继承让类与类之间产生了关系,类的耦合性增强了,父类发生变化子类也会跟着改变
//子类继承父类 (继承前面的Animal)
public class Dog extends Animal{
public Dog(){
super();
System.out.println("---dog---无参的构造方法------");
}
public Dog(String name,int age){
super(name, age);
}
//测试
public static void main(String[] args) {
Dog dog = new Dog();
Dog d2 =new Dog("狗",10);
System.out.println(d2.name+",age:"+d2.age);
}
}
运行结果:
------无参的构造方法------
—dog—无参的构造方法------
------有参的构造方法------
狗,age:10
继承中的构造方法
- 创建有继承关系的子类对象时,会先执行父类中默认的构造方法,然后执行子类中相关的构造方法
- 如果父类中不存在默认的构造方法,那么此时的解决问题,第一种就是手动添加一个默认的构造方法。
super关键字
- 表示当前类的父类的引用
- 只能出现在有继承关系的子类中
- super两种用法:
- super.属性名、super.方法名(参数列表)
- 表示父类的属性和方法,和子类中的属性或方法重名时使用
- super(参数列表)
- 出现在子类构造方法的第一句代码时
- 就是通过参数列表匹配父类的构造方法来创建父类对象
- super.属性名、super.方法名(参数列表)
多态
多态就是同一函数在不同类中有不同的实现;
- 面向对象的多态性,即“一个接口,多个方法”。
- 多态性体现在父类中定义的属性和方法被子类继承后,可以具有不同的属性或表现方式。
- 多态性允许一个接口被多个同类使用,弥补了单继承的不足。
实例:
//父类
public class Animal {
public void talk(){
System.out.println("讲话");
}
}
*******************************************
//子类
public class Cat extends Animal{
public void talk(){
System.out.println("喵喵");
}
}
*******************************************
//子类
public class Dog extends Animal{
public void talk(){
System.out.println("汪汪");
}
}
*******************************************
//测试类
public class Test {
public static void main(String[] args) {
Animal animal = new Animal();
animal.talk();
//以父类的名义实例化
Animal dog = new Dog();
//以子类自己的方法实现
dog.talk();
Animal cat = new Cat();
cat.talk();
}
}
运行结果:
讲话
汪汪
喵喵
利用父类类型实例化,子类覆写父类的方法后,运行时,动态的再指向子类的实现,即为多态 详解
对象的内存分析
- 通过上图分析,我们可以理解,在栈内存中运行的方法,遵循“先进后出,后进先出”,对象b指向堆内存中的空间,在调用方法时,也去堆内存中寻找方法信息,然后去方法区执行对应的方法