面向对象概述以及三大特征

一、类与对象的概述
现实世界中是如何描述一个事物的呢?
举例:学生
姓名,年龄,性别…
学习,吃饭,睡觉

属性:该事物的描述信息
行为:该事物能够做什么

我们学习编程语言,是为了模拟现实世界的事物的。而我们学习的编程语言Java中最基本的单位是:类。所以,我们就应该把事物通过类来体现出来:
由此,我们就得到了现实世界事物和类的对应关系:

事物: 类:
属性 成员变量
行为 成员方法

类:是一组相关的属性和行为的集合。是一个抽象的概念。
格式:
修饰符 class 类名 {
构造器……
方法……
字段……
}
对象:是该类事物的具体表现形式。具体存在的个体。
格式:类名 对象名 = new 类名();
Person p = new Person();

举例:
学生:类
班长:对象

类:对现实生活中事物的描述。

对象:实实在在存在的类的个体。

二、什么是面向对象

1:面向对象思想

     面向对象是基于面向过程的编程思想。



     面向过程:强调的是每一个功能的步骤

     面向对象:强调的是对象,然后由对象去调用功能

2:面向对象的思想特点

     A:是一种更符合我们思想习惯的思想

     B:可以将复杂的事情简单化

     C:将我们从执行者变成了指挥者



     举例:

               买电脑:

                        面向过程:我的了解电脑--了解我自己的需求--找对应的参数信息--去中关村买电脑--讨价还价--买回电脑

                        面向对象:我知道我要买电脑-- 班长去给我买 -- 班长就买回来了

               洗衣服:

                        面向过程:把衣服脱下--找一个盆--放点洗衣粉--加点水--把衣服扔进去--搓一搓--清洗衣服--拧干--晾起来

                        面向对象:把衣服脱下--打开全自动洗衣机--扔进去--一键即可--晾起来

               吃饭:

                        面向过程:去超市买菜--摘菜--洗菜--切菜--炒菜--盛起来--吃

                        面向对象:上饭店吃饭,你--服务员(点菜)--厨师(做菜)--服务员(端菜)--吃

3.:开发,设计,特征
面向对象开发
就是不断的创建对象,使用对象,指挥对象做事情。

面向对象设计
其实就是在管理和维护对象之间的关系。

面向对象特征
封装(encapsulation)
继承(inheritance)
多态(polymorphism)

三、自定义类

事物:
属性 事物的信息描述
行为 事物的功能

类:
成员变量 事物的属性
成员方法 事物的行为

定义一个类,其实就是定义该类的成员变量和成员方法。

实际上,类的一般组成:
成员变量
构造方法
成员方法
根据返回值:
void类型
非void类型
形式参数:
空参方法
非空参方法
一个标准代码的最终版。

学生类:
成员变量:
name,age
构造方法:
无参,带两个参
成员方法:
getXxx()/setXxx()
show():输出该类的所有成员变量值

给成员变量赋值:
A:setXxx()方法
B:构造方法

输出成员变量值的方式:
A:通过getXxx()分别获取然后拼接
B:通过调用show()方法搞定

1、成员变量和局部变量的区别?

A:在类中的位置不同
成员变量:在类中方法外
局部变量:在方法定义中或者方法声明上
B:在内存中的位置不同
成员变量:在堆内存
局部变量:在栈内存
C:生命周期不同
成员变量:随着对象的创建而存在,随着对象的消失而消失
局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
D:初始化值不同
成员变量:有默认初始化值
局部变量:没有默认初始化值,必须定义,赋值,然后才能使用。

注意事项:
局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则。

2、形式参数的问题:

基本类型:形式参数的改变不影响实际参数
引用类型:形式参数的改变直接影响实际参数
如果你看到了一个方法的形式参数是一个类类型(引用类型),这里其实需要的是该类的对象。

3、匿名对象:
就是没有名字的对象。
A:调用方法,仅仅只调用一次的时候。
注意:调用多次的时候,不适合。
匿名调用的好处
匿名对象调用完毕就是垃圾。可以被垃圾回收器回收。
B:匿名对象可以作为实际参数传递
4、创建对象做了哪些事情:

Student s = new Student();
A:把Student.class文件加载到内存
B:在栈内存给s变量开辟了一个空间
C:在堆内存为学生对象申请了一个空间
D:给成员变量进行了默认初始化。null、0
E:给成员变量进行显示初始化。张三,23
F:通过构造方法给成员变量进行初始化。李四,24
G:数据初始化完毕,然后把堆内存的地址值赋值给栈内存的s变量。

四、面向对象三大特征

1.封装(encapsulation)

封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。

->好处:将变化隔离

便于使用

提高复用性

提高安全性

->封装原则:

将不需要对外提供的内容都隐藏起来

把属性都隐藏,提供公共方法对其访问
private权限修饰符

可以修饰成员变量和成员方法
被其修饰的成员只能在本类中被访问

this关键字

this: 是当前类的对象引用。简单的记,它就代表当前类的一个对象。
当定义类中功能时,该函数内部要用到调用该函数的对象时,这时用this来表示这个对象。但凡本类功能内部使用到了本类对象,都用this表示。

注意:(1)谁调用这个方法,在该方法内部的this就代表谁。
(2)用this调用构造函数,必须定义在构造函数的第一行。因为构造函数是用于初始化的,所以初始化动作一定要执行。否则编译失败。

this的场景:
解决局部变量隐藏成员变量

static关键字:

static是一个修饰符,用于修饰成员变量和成员函数上。可以直接类名调用。
特点:
①随着类的加载而加载,先有静态,后有对象产生
②被所有对象所共享。
③可以直接被类名所调用。
弊端:
①有些数据是对象特有的数据,是不可以被静态修饰的。因为那样的话,特有数据会变成对象的共享数据。这样对事物的描述就出了问题。所以,在定义静态时,必须要明确,这个数据是否是被对象所共享的。
②静态方法只能访问静态成员,不可以访问非静态成员。
因为静态方法加载时,优先于对象存在,所以没有办法访问对象中的成员。
③静态方法中不能使用this,super关键字。
因为this代表对象,而静态在时,有可能没有对象,所以this无法使用。
④主函数是静态的。

静态成员变量又称为类变量,而非静态成员变量成为实例变量。
成员变量和静态变量的区别:
①成员变量所属于对象。所以也称为实例变量。
静态变量所属于类。所以也称为类变量。
②成员变量存在于堆内存中。
静态变量存在于方法区中。
③实例变量生命周期短,随着对象创建而存在,随着对象被回收而消失。
静态变量生命周期长,随着类的加载而存在,随着类的消失而消失。
④成员变量只能被对象所调用 。
静态变量可以被对象调用,也可以被类名调用。
所以,成员变量可以称为对象的特有数据,静态变量称为对象的共享数据。

static关键字注意事项
A:在静态方法中是没有this关键字的
如何理解呢?
静态是随着类的加载而加载,this是随着对象的创建而存在。
静态比对象先存在。
B:静态方法只能访问静态的成员变量和静态的成员方法
静态方法:
成员变量:只能访问静态变量
成员方法:只能访问静态成员方法
非静态方法:
成员变量:可以是静态的,也可以是非静态的
成员方法:可是是静态的成员方法,也可以是非静态的成员方法。
简单记:
静态只能访问静态。

构造方法:
创建对象时,给对象的数据进行初始化

格式:
A:方法名与类名相同
B:没有返回值类型,连void都没有
C:没有具体的返回值
构造方法的注意事项:
A:如果我们没有给出构造方法,系统将自动提供一个无参构造方法。
B:如果我们给出了构造方法,系统将不再提供默认的无参构造方法。
注意:这个时候,如果我们还想使用无参构造方法,就必须自己给出。建议永远自己给出无参构造方法

给成员变量赋值有两种方式:
A:setXxx()
B:构造方法

两个小问题:

变量什么时候定义为成员变量:
如果这个变量是用来描述这个类的信息的,那么,该变量就应该定义为成员变量。
原因:类是一组相关的属性和行为的集合,并且类是通过事物转换过来的,而类中的成员变量就是事物的属性,是用来描述事物的。同理:成员变量其实是用来描述类的。

变量到底定义在哪里好呢?
变量的范围是越小越好。因为能及时的被回收。

main方法的格式讲解:

public static void main(String[] args) {…}

public:公共的,访问权限是最大的。由于main方法是被jvm调用,所以权限要够大。
static:静态的,不需要创建对象,通过类名就可以。方便jvm的调用。
void:因为我们曾经说过,方法的返回值是返回给调用者,而main方法是被jvm调用。你返回内容给jvm没有意义。
main:是一个常见的方法入口。我见过的语言都是以main作为入口。
String[] args:这是一个字符串数组
代码块

(1)用{}括起来的代码。
(2)分类:
A:局部代码块
局部位置,用于限定变量的生命周期,及早释放,提高内存利用率。
B:构造代码块
在类中的成员位置,用{}括起来的代码。每次调用构造方法执行前,都会先执行构造代码块。
把多个构造方法中相同的代码可以放到这里,每个构造方法执行前,首先执行构造代码块。
C:静态代码块
在类中的成员位置,用{}括起来的代码,只不过它用static修饰了。
对类的数据进行初始化,仅仅只执行一次。
(3)静态代码块,构造代码块,构造方法的顺序问题?
静态代码块 > 构造代码块 > 构造方法
类的初始化顺序如下:
父类静态变量——>父类静态块——>子类静态变量——>子类静态块——>父类变量
——>父类普通块父类构造函数(子类实例化时先要调用父类构造函数)
——>子类变量——>子类普通块——>子类构造函数
如果有多个初始化块,则按照代码先后顺序执行。
2.继承(inheritance)

(1)把多个类中相同的成员给提取出来定义到一个独立的类中。然后让这多个类和该独立的类产生一个关系,
这多个类就具备了这些内容。这个关系叫继承。
(2)Java中如何表示继承呢?格式是什么呢?
A:用关键字extends表示
B:格式:
class 子类名 extends 父类名 {}
(3)继承的好处:
A:提高了代码的复用性
B:提高了代码的维护性
C:让类与类产生了一个关系,是多态的前提
(4)继承的弊端:
A:让类的耦合性增强。这样某个类的改变,就会影响其他和该类相关的类。
原则:低耦合,高内聚。
耦合:类与类的关系
内聚:自己完成某件事情的能力
B:打破了封装性
(5)Java中继承的特点
A:Java中类只支持单继承
B:Java中可以多层(重)继承(继承体系)
(6)继承的注意事项:
A:子类不能继承父类的私有成员
B:子类不能继承父类的构造方法,但是可以通过super去访问
C:不要为了部分功能而去继承
(7)什么时候使用继承呢?
A:继承体现的是:is a的关系。
B:采用假设法
(8)Java继承中的成员关系
A:成员变量
a:子类的成员变量名称和父类中的成员变量名称不一样,这个太简单
b:子类的成员变量名称和父类中的成员变量名称一样,这个怎么访问呢?
子类的方法访问变量的查找顺序:
在子类方法的局部范围找,有就使用。
在子类的成员范围找,有就使用。
在父类的成员范围找,有就使用。
找不到,就报错。
B:构造方法
a:子类的构造方法默认会去访问父类的无参构造方法
是为了子类访问父类数据的初始化
b:父类中如果没有无参构造方法,怎么办?
子类通过super去明确调用带参构造
子类通过this调用本身的其他构造,但是一定会有一个去访问了父类的构造
让父类提供无参构造
C:成员方法
a:子类的成员方法和父类中的成员方法名称不一样,这个太简单
b:子类的成员方法和父类中的成员方法名称一样,这个怎么访问呢?
通过子类对象访问一个方法的查找顺序:
在子类中找,有就使用
在父类中找,有就使用
找不到,就报错

super关键字
1.在Java中,this通常指当前对象,super则指父类的。
2.子类的构造函数如果要引用super的话,必须把super放在函数的首位.
3.在Java中,有时还会遇到子类中的成员变量或方法与超类(有时也称父类)中的成员变量或方法同名。因为子类中的成员变量或方法名优先级高,所以子类中的同名成员变量或方法就隐藏了超类的成员变量或方法,但是我们如果想要使用超类中的这个成员变量或方法,就需要用到super.
4.用super直接传递参数

this和super的异同

1)super(参数):调用基类中的某一个构造函数(应该为构造函数中的第一条语句)

2)this(参数):调用本类中另一种形成的构造函数(应该为构造函数中的第一条语句)
3)super: 它引用当前对象的直接父类中的成员(用来访问直接父类中被隐藏的父类中成员数据或函数,基类与派生类中有相同成员定义时如:super.变量名 super.成员函数据名(实参)

4)this:它代表当前对象名(在程序中易产生二义性之处,应使用this来指明当前对象;如果函数的形参与类中的成员数据同名,这时需用this来指明成员变量名)

5)调用super()必须写在子类构造方法的第一行,否则编译不通过。每个子类构造方法的第一条语句,都是隐含地调用super(),如果父类没有这种形式的构造函数,那么在编译的时候就会报错。

  6)super()和this()类似,区别是,super()从子类中调用父类的构造方法,this()在同一类内调用其它方法。

  7)super()和this()均需放在构造方法内第一行。

  8)尽管可以用this调用一个构造器,但却不能调用两个。

  9)this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。

  10)this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块。

  11)从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。
方法重写

方法重写:子类中出现了和父类中方法声明一模一样的方法。
子类对象调用方法的时候:
先找子类本身,再找父类。
方法重写的应用:
当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法。
这样,即沿袭了父类的功能,又定义了子类特有的内容。
方法重写的注意事项
A:父类中私有方法不能被重写
因为父类私有方法子类根本就无法继承
B:子类重写父类方法时,访问权限不能更低
最好就一致
C:父类静态方法,子类也必须通过静态方法进行重写
子类重写父类方法的时候,最好声明一模一样。

final关键字

(1)由于继承中方法有一个现象:方法重写。所以,父类的功能,就会被子类给覆盖调。
有些时候,我们不想让子类去覆盖掉父类的功能,只能让他使用。针对这种情况,Java就提供了一个关键字:final

final:最终的意思。常见的是它可以修饰类,方法,变量。

(2)特点:
A:它修饰的类,不能被继承。
B:它修饰的方法,不能被重写。
C:它修饰的变量,是一个常量。
(3)面试相关:
A:局部变量
a:基本类型 值不能发生改变
b:引用类型 地址值不能发生改变,但是对象的内容是可以改变的
B:初始化时机
a:只能初始化一次。
b:常见的给值
定义的时候。(推荐)
构造方法中。

两道面试题:

1:方法重写和方法重载的区别?方法重载能改变返回值类型吗?
方法重写:
在子类中,出现和父类中一模一样的方法声明的现象。
方法重载:
同一个类中,出现的方法名相同,参数列表不同的现象。
方法重载能改变返回值类型,因为它和返回值类型无关。
Override:方法重写
Overload:方法重载

2:this关键字和super关键字分别代表什么?以及他们各自的使用场景和作用。

this:代表当前类的对象引用
super:代表父类存储空间的标识。(可以理解为父类的引用,通过这个东西可以访问父类的成员)

场景:
成员变量:
this.成员变量
super.成员变量
构造方法:
this(…)
super(…)
成员方法:
this.成员方法
super.成员方法

3.多态(polymorphism)

多态是指同一个对象在不同时刻体现出来的不同状态。

(1)实现多态的机制:

 父类的引用变量可以指向子类的实例对象,而程序调用的方法在运行期才动态绑定,就是引用变量所指向的真正实例对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。

多态的作用:把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。

(2)多态的前提:
A:有继承或者实现关系。
B:有方法重写。
C:有父类或者父接口引用指向子类对象。

多态的分类:
a:具体类多态
class Fu {}
class Zi extends Fu {}

Fu f = new Zi();
b:抽象类多态
abstract class Fu {}
class Zi extends Fu {}

Fu f = new Zi();
c:接口多态
interface Fu {}
class Zi implements Fu {}

Fu f = new Zi();
(3)多态中的成员访问特点
A:成员变量
编译看左边,运行看左边
B:构造方法
子类的构造都会默认访问父类构造
C:成员方法
编译看左边,运行看右边
D:静态方法
编译看左边,运行看左边

为什么?
因为成员方法有重写。

(4)多态的好处:
A:提高代码的维护性(继承体现)
B:提高代码的扩展性(多态体现)
(5)多态的弊端:
父不能使用子的特有功能。

现象:
子可以当作父使用,父不能当作子使用。

多态中引用变量类型转换

向上转型(子类→父类):(自动完成)

 父类名称 父类对象 = 子类实例 ;

向下转型(父类→子类):(强制完成)

 子类名称 子类对象 = (子类名称)父类实例 ;

论坛武侠例子帮助理解:

继承:你有一个武林高手师父,人称“玉罗刹”,然后你从你师傅那里学到了他的全部武功。

 扩展:后来你又自创了你自己的武功。

 多态:你现在可以用你师傅的名号“玉罗刹”去行侠仗义,你师父会的你都会。别人可以认为你就是你师父。但是,你不能使用你自己的武功,因为你还带着“玉罗刹”的面具。如果你想要使用自己的武功,就必须先拿下面具(使用强制转换,将父类对象引用转换成子类对象类型)。

java不允许的:你师父不会使用你的武功,所以你师父不能伪装成你(父类对象不能强转成子类对象类型)

 然而,你的师傅可以收很多的徒弟,每个徒弟都可以修炼自己的武功,所以到最后,你师父能干的事,他的徒弟们都可以取代他的位置
class A//玉罗刹  
{  
public void Jiuyinzhenjing()//九阴真经  
{  
System.out.println("this is A Say");  
}  
}  

class B extends A//你继承了你师父的全部武学  
{  
public void Rulaishenzhang()//如来神掌  
{  
System.out.println("this is B Sing");  
}  
}  
public class Duotai   
{  
public static void main(String[] args)  
{  
A shifu = new B();  
shifu.Jiuyinzhenjing();//使用“玉罗刹”的名号使用九阴真经  
B tudi= new B();  
tudi.Jiuyinzhenjing();//使用师父的九阴真经  
tudi.Rulaishenzhang();//自己使用如来神掌  

//a.Rulaishenzhang();//不可以,你师父不会如来神掌  
B you;  
you = (B)shifu;//你拿下面具,露出真面目,可以使用如来神掌了  
you.Rulaishenzhang();   

Sharen(shifu);//师父用九阴真经去杀了10000人  
Sharen(tudi);//徒弟也可以用九阴真经去杀10000人  

}  
public static void Sharen(A a)//师父的绝学九阴真经杀人  
{  
a.Jiuyinzhenjing();  
System.out.println("使用九阴真经杀了10000人!");  
}  
}  
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值