面向对象初步

面向对象基础

面向对象方法有三个基本特征:

  1. 封装(Encapsulation):将对象的实现细节隐藏起来,然后通过一些公用方法来暴露该对象的功能;
  2. 继承(Inheritance):当子类继承父类后,子类作为一种特殊的父类,将直接获得父类的属性和方法;是实现软件复用的重要手段;
  3. 多态(Polymorphism):子类对象可以直接赋值给父类变量,但运行时依然会表现出子类的特征:这就意味着同一个类型的对象在执行同一个方法时,可能会表现出不同的行为特征。

类和对象

  • 类是具有共同属性、共同方法的一类事物。类是对象的抽象;对象是类的实例。类是整个软件系统最小的程序单元。类的封装性将各种信息细节隐藏起来,并通过公用方法来暴露该类对外所提供的功能,从而提高了类的内聚性,降低了对象之间的耦合性。
    消息是实例与实例之间相互通信的机制。
  • 基于对象(javascript):没有继承和多态:无法让开发者派生出新的类。 类之间的结构关系:

一般→特殊:(is a)用extends。
整体→局部:(has a )用组合:在一个类里面保存另一个对象的引用。
可以把类当成是一种自定义类型,可以使用类来定义变量,这种类型的变量统称为引用变量。也就是说,所有类是引用类型。

定义类的语法:

{public∪final∪abstract} class 类名
{
    构造器定义<sup>*</sup>;//是一个类创建实例的根本途径。通过new来调用构造器,从而返回该类的实例。
    成员变量<sup>*<sup>;//用于定义该类或者该类的实例所包含的**状态数据**
    方法<sup>*<sup>;//用于定义该类或者该类实例的行为特征或者功能实现
}
//类名首字母要大写
//static修饰的成员不能访问没有static修饰的成员

定义成员变量的语法:

∅∪{publicprotectedprivate}∩{e,static,final} 类型 成员变量名 { = default };
//类型:基本数据类型和引用类型;
//成员变量名:第一个首字母小写;

定义方法语法:

∅∪{publicprotectedprivate}∩{e,abstract,final}∩{e,static} 方法返回值类型 方法名 (形参列表)
{
    //
}
//方法名一般以英文动词开头;
//static修饰的成员属于类本身,既可以通过类来调用,也可以通过实例来调用;否则属于实例,只能由实例来调用。因而静态变量不能访问非静态变量;

定义构造器语法:

{publicprotectedprivate} 类名(形参列表)
{
}
//若定义了返回值,或定义了void, 则被认为是方法而非构造器。

对象引用和指针

区分变量和对象

Person p = new Person();

在这里p**变量**是一个引用(只存储了地址值,并未包含任何实际的数据),被存放在栈内存里,指向实际的Person对象;
真正的Person**对象**则存放在堆内存中。
Java程序不允许直接访问堆内存中的对象,只能通过该对象的引用操作该对象。也就是说,不管是数组还是对象,都只能通过引用来访问它们。当访问引用变量的成员变量和方法时,实际上访问的是被引用对象的成员变量和方法。
允许多个引用指向同一个对象Person p2 = p;。在这里p2和p变量指向同一个对象。

对象的this引用

this 可以代表任何对象(因而不能用static修饰),当this出现在方法体中时,它所代表的对象是不确定的,但他的类型是确定的:它所代表的类型只能是当前类的实例;只有当这个方法被调用时,它所代表的对象才被确定下来:谁在调用这个方法,this 就代表谁。Java允许一个成员调用另一个成员,这是可以省略this前缀。
如果想在静态方法中访问一个普通方法,则只能重新创建一个对象。
若成员变量和局部变量重名而我们又要访问成员变量时,必须对成员变量使用this前缀。
如果在某个方法中把this作为返回值返回,则可以连续调用同一个方法从而使代码更加整洁。

方法详解

方法的属性

方法不能独立定义,只能在类里面定义。
方法要么属于一个类(static),要么属于该类的一个对象。(使用该类的任何对象调用static方法时会得到相同的执行结果)
不能独立的执行方法,必须使用类或者对象来调用方法。
确定方法的三要素:

  1. 调用者:方法的所属人:类还是对象;
  2. 方法名;
  3. 形参列表(方法重载的依据)。

方法的参数传递机制

值传递:将参数的副本(复制品)传入方法内,而参数本身不会受到影响。
对于引用类型的参数传递来说:传递(复制了)了引用变量,但是操作的对象是同一个。

形参个数可变方法

public void bookCounter(int a , String... books)//后面不是数组,却用数组的方式遍历。一个方法只能有一个可变个数的形参。
{
    for(String book : books)
    {
        a ++;
    }
}

成员变量和局部变量

这里写图片描述
类变量的生命周期:类的准备阶段→完全销毁;作用域与这个类的生存范围相同。
实例变量生命周期:实例被创建→系统完全销毁这个实例;作用域与对应实例的生存范围相同。
类变量的作用域比实例变量的作用域更大:实例变量随着实例的存在而存在,而类变量则随类的存在而存在。实例也可以访问类变量,同一个类的所有实例变量访问类变量时,实际上访问的是该类本身的同一个变量,即同一片内存区。
类的生命周期:类加载,类验证,类准备,类解析,类初始化
成员变量无需初始化。
局部变量除了形参外,都需要显示初始化。形参的初始化在调用该方法时由系统完成,形参的值由方法的调用者负责制定。
当通过类或者对象调用某个方法时,系统会在该方法栈区内为所有的形参分配内存空间,并将实参的值赋给对应的形参,这就完成了形参的初始化。

成员变量初始化和内存中的运行机制

系统通常在第一次使用某个类的时候加载并初始化:在准备阶段,在堆内存中为类分配一块内存区(创建一个类对象),在这块内存区中包含保存类变量的内存,并对类变量设置初始值。(没有对实例变量做任何操作)
实例变量是在创建实例时分配内存空间并指定初值的。再次创建实例时,不需要对类做初始化。

局部变量初始化和内存中的运行机制

局部变量定义后,必须经过显示初始化才能使用,系统不会为局部变量执行初始化。
这意味着定义了局部变量后,系统并未为这个局部变量分配内存空间直到等到程序为这个变量赋值初始值时,系统才会给局部变量分配内存,并将初始值保存到这块内存中。
与成员变量不同,局部变量不属于任何类或实例,因此它总是保存在其所在方法的栈内存中。如果局部变量是基本类型变量,则直接把变量值存放在栈中,如果是引用类型,则存放地址在栈中。
栈内存中的变量无须系统垃圾回收,变量是随方法或代码块的运行结束而结束的。因此,局部变量的作用域是从初始化该变量开始,知道该方法或该代码块运行完成而结束。因为局部变量只保存基本类型的值或对象的引用,因此局部变量所占的内存通常较小。

变量的使用规则

成员变量的定义是被放到堆内存中去,成员变量的作用域是类和对象存在的范围所以存在两种坏处。
1)增加了变量的生存时间,将增大了系统的消耗
2)扩大的变量作用域,不利于提高程序的内聚性。

所以以下三方面应该考虑成员变量:
1)描述类或这对象的固定信息时;例如人有身高,名字,年龄等。
2)多个方法之间共享的信息需要用成员变量保存。
3)需要保存该类或者对象运行时的状态信息需要用成员变量。

局部变量的范围越小,他在内存里停留的时间就越短,程序的性能就越好。因此,能用代码块局部变量的地方,就坚决不能用方法局部变量。

隐藏和封装

理解封装

使用访问控制符:private,default,protected,public

  1. private 访问控制级别:只能在该类的内部被访问,很显然,这个访问控制符用于修饰属性最合适,使用他来修饰属性就可以把属性隐藏在类的内部
  2. default访问控制权限,如果属性或者方法不使用任何修饰符,则是默认default修饰符,可以被相同包下其他访问,
  3. protected,可以被同一个包中其他类访问,也可以被不同包中的子类访问
  4. public访问控制权限,这是一个最宽松的访问控制级别,可以被所有类访问

注意:

  • 对于局部变量而言,其作用域就是它所在的方法,不可能被其他类来访问,因此不能使用访问控制符来修饰。

在定义了private变量之后,只能类内部成员来操作和访问,在该类之外只能通过各自对应的setter和getter方法来操作和访问他们

注意:java类里的属性的setter和getter方法有非常重要的意义,例如某个类里包含了一个名为abc的属性,则其对应的setter和getter方法名应为setAbc和getAbc,如果一个java类的每个属性都被使用private修饰,并为每个属性都提供public修饰setter和getter方法,这个类就是一个符合java规范的类。

关于访问控制符的使用,存在如下基本原则:

  1. 类里的绝大部分属性都应该使用private修饰,除了一些static修饰的,类似全局变量的属性,才可能考虑使用public修饰符,除此之外,有些方法只是用于辅助实现该类的其他方法,这些方法被称为工具方法,工具方法也应该使用private修饰
  2. 如果某个类主要用作其他类的父类,该类里包含的大部分方法可能仅仅希望被其子类重写,而不想被外界直接调用,则应该使用protected修饰这些方法
  3. 希望暴露出来给其他类自由调用的方法应该使用public修饰,因此,类的构造器通过使用public修饰,暴露给其他类中创建该类的对象,因为顶级类通常都希望被其他类自由使用,所以大部分顶级类都用public修饰
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值