面向对象(上)

类与对象

定义:类是一个模板,对象才是类可以使用的实例,先有类再有对象
在类中一般偶读会有两个组成:
1.成员属性(field):简化成为属性;
2.操作方法(method):定义对象具有的处理行为;
在这里插入图片描述
产生对象必须使用如下格式来完成
声明并实例化对象:类名称 对象名称=new 类名称();
实例化对象: 对象名称=new 类名称();

对象内存分析:
两块最常用的内存空间:

  1. 堆内存:保存的是对象的具体信息,在程序之中堆内存空间的开辟是通过new完成的;
  2. 站内存:保存的是一块堆内存的地址,即通过地址找到堆内存

应用传递分析
引用数据类型就必然牵扯到内存的引用传递:同一个堆内存可以被不同的栈内存所指向,也可以更换指向。
在这里插入图片描述
在这里插入图片描述

引用与垃圾产生分析
在这里插入图片描述

属性封装

1、封装的含义:封装是实现面向对象程序设计的第一步,封装就是将数据或函数等集合在一个个的单元中(我们称之为类)。被封装的对象通常被称为抽象数据类型。

2、封装的作用:封装的作用在于保护或者防止代码(数据)被我们无意中破坏。在面向对象程序设计中数据被看作是一个中心的元素并且和使用它的函数结合的很密切,从而保护它不被其它的函数意外的修改。

3、如何封装:封装提供了一个有效的途径来保护数据不被意外的破坏。相比我们将数据(用域来实现)在程序中定义为公用的(public)我们将它们(fields)定义为私有的(private)在很多方面会更好。私有的数据可以用两种方式来间接的控制。第一种方法,我们使用传统的存、取方法。第二种方法我们用属性(property),使用属性不仅可以控制存取数据的合法性,同时也提供了“读写”、“只读”、“只写”灵活的操作方法。

4、什么情况下封装:编写实例类时,用到封装有很多好处,其中比较实际的是:

拒绝直接调用声明字段,保护内部数据,更安全;
在编程中可达到缓存的效果,执行效率高;
重复调用,避免代码冗余,程序编写效率高。

构造方法与匿名对象

**构造方法**:
可以通过构造方法实现实例化对象中的属性初始化处理。定义要求如下:
1.	构造方法名称必须和类名称一致。
2.	构造方法不允许设置任何的返回值类型
3.	构造方法是使用关键字new实例化对象的时候自动调用
结论:一个类至少存在有一个构造方法,永恒存在。
构造方法:是在类对象实例化的时候调用的,而普通方法是在类对象实例化参数之后调用的(如果使用viod构造方法会变成普遍方法)

匿名对象
new Person(“zhangsan”,10).tell(); //匿名对象
此时依然通过了对象进行类由tell()方法的调用,但是由于此对象没有任何的引用名称,所以该对象使用一次之后就将成为垃圾,所有的垃圾将被GC进行回收与释放
在这里插入图片描述

this关键字

this的三种描述:

  1. 当前类中的属性:this属性;
  2. 当前类中的方法(普通方法,构造方法);
    this.方法;
    this();(使用无参构造方法)
    构造方法必须在实例化新对象的时候调用,所以“this()”的调用只能在构造方法的第一行。
  3. 描述当前对象;

static

声明static属性

  1. static属性是一个全局数据
    在这里插入图片描述

  2. static属性可以由类名称直接调用。Preson.country=”……….”;
    定义static方法
    特点:可以直接有类名称在没有实例化对象的情况下进行调用。
    方法就有了两种:static方法和非static方法。
    static方法只能调用static属性和static方法
    非static方法能调用static属性和static方法
    static定义的方法或者属性都不是你代码编写之初需要考虑的,职业在回避 例化对象调用并且描述公共属性的情况下才会考虑static定义的方法或者是属性。

继承

继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。

继承的作用:通过继承可以快速创建新的类,实现代码的重用,提高程序的可维护性,节省大量创建新类的时间,提高开发效率和开发质量。
注意:
1.子类不能选择性继承父类;
2.Java不支持多重继承,但一个类可以实现多个接口,从而克服单继承的缺点;
3.构造方法不会被子类继承,但可以从子类中调用父类的构造方法。
优点:
1.继承过来的字段和方法,可以像任何其他字段和方法一样被直接使用;
2.在子类中可以声明一个与父类中同名的新字段或静态方法,从而“隐藏”父类中的字段或方法;
3.可以在子类中声明一个在父类中没有的新字段和方法;
4.可以在子类中编写一个父类当中具有相同名的新实例方法,这称为“方法重写”或“方法覆盖”;
5.可以在子类中编写一个调用父类构造方法的子类构造方法,既可以隐式地实现,也可以通过使用关键字super来实现。

方法的覆写

发现父类中设计不足并且需要保留有父类中的方法或者属性名称的情况下使用方法的覆写。
当子类定义了与父类方法名称相同,参数类型及个数完全相同时则就称为方法的覆写。
如果子类还行继续调用父类的方法,就必须使用“super.方法()”
覆写的限制
子类的访问控制权限不能比父类的跟严格:public>default>private;
面试题:请解释Override(重写)和Overloading(重载)的区别?
Overloading:方法名称相同,参数的类型及个数不同,没有权限限制,发生在一个类中。
Override:方法名称,参数类型及个数完全相同,子类的访问权限限制不能比父类跟严格,发生在继承关系的类中。
进行方法重载的时候并没有对返回类型做出限制,但是好的习惯应该保持一致。
属性的覆盖
子类定义了与父类相同名称的成员时就是属性的覆盖

子类访问父类私有成员
子类继承其父类的所有public和protected成员,但不能继承其父类的private成员。那么如何在子类中访问到父类中的字段呢,我们可以在父类中提供用来访问其私有字段的public或protected方法,子类使用这些方法来访问相应的字段。
使用super关键字
使用super调用父类中重写的方法、访问父类中被隐藏的字段
使用super调用父类的无参数构造方法/有参数构造方法
子类不继承其父类的构造方法。
当使用无参数的super()时,父类的无参数构造方法就会被调用;
当使用带有参数的super()方法时,父类的有参数构造方法就会被调用。
面试题:this与super的区别
this首先是在本类中寻找对象再去父类中寻找,super直接在父类中查找。
This和super都可以进行构造方法的调用,this调用的是本类构造,super调用的是父类调用,但是两个方法都必须放在构造方法首行,所以不能同时出现;

多态

多态在基础性的基础之上扩展处理的父子类互相转换处理。
基本概念:
方法的多态性:
方法的重载:
方法的覆写:
对象的多态性:父子实例之间的转换处理,两种模式
对象的向上转型:父类 父类实例=子类实例,自动完成转换(90%使用)
对象的向下转型:子类 子类实例=(子类)父类实例,强制完成转换(3%),不需要转型(例如:string 7%)
在进行向下转型的前提是先进行了向上转型!!所以向下转型并不是一件安全的事情。(不常用)
Instanceof
向下转型本身是有隐患的,所以为了保证向下转型的正确性,往往需要在进行转型之前进行判断,判断某个实例是否是某个类的对象就通过instanceof语句:
对象 instanceof 类; (返回一个boolean类型,如果是true表示实例是指定类对象)
*

final关键字

final在程序中描述的是终结器的作用,定义后是不能够继承的类,不能被覆写的方法以及常量。
Final在表示常量是常量名必须都是大写
Final也表示一个常量的概念

Object类

在java中只有一个类不存在有继承关系,在默认情况下所有的类都是object的子类。
获取对象信息:toString(); toString():取得对象信息,返回该对象的字符串表示。
equals() String类对象比较 使用的是 equals()方法,实际上String类的equals()方法就是覆写 Object类中的equals()方法。

抽象类

在进行父类设计时,优先考虑的一定是抽象类。
基本定义:主要作用对子类的覆写方法进行约定,在抽象类礼包定义一些抽象方法实现这样的约定,抽象方法指使用了abstract关键字定义并没有提供方法体的方法。抽象方法必须在抽象类中,抽象类必须使用absract定义。
抽象类的使用:
1抽象类的使用原则如下:
(1)抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public;
(2)抽象类不能直接实例化,需要依靠子类采用向上转型的方式处理;
(3)抽象类必须有子类,使用extends继承,一个子类只能继承一个抽象类;
(4)子类(如果不是抽象类)则必须覆写抽象类之中的全部抽象方法(如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。

相关说明:

  1. 定义抽象类绝对不能够使用final关键字来进行定义,因为抽象类必须有子类,而final是不能够有子类的。
  2. 抽象类是作为一个普通类的加强版出现的(普通类扩展而来的)所以一定可以提供有构造方法,并且子类也一定会按照父类对象的实例化原则进行父类构造。
  3. 抽象类中允许没有抽象方法,但是没办法直接使用new实例化对象。必须依靠子类对象完成。
  4. 抽象类中可以提供static方法,并且该方法不受抽象类对象的局限。

包装类

我们知道基本数据类型包括byte, short, int, long, float, double, char, boolean,对应的包装类分别是Byte, Short, Integer, Long, Float, Double, Character, Boolean。关于基本数据类型的介绍可参考八大基本数据类型

JAVA是面向对象的语言,很多类和方法中的参数都需使用对象(例如集合),但基本数据类型却不是面向对象的,这就造成了很多不便。

如:List = new ArrayList<>();,就无法编译通过

为了解决该问题,我们引入了包装类,顾名思义,就是将基本类型“包装起来“,使其具备对象的性质,包括可以添加属性和方法,位于java.lang包下。

拆箱与装箱
既然有了基本数据类型和包装类,就必然存在它们之间的转换,如:


public static void main(String[] args) {
    Integer a = 0;
    for(int i = 0; i < 100; i++){
        a += i;
    }
}

将基本数据类型转化为对应类型的包装类的过程叫“装箱”;将包装类转为对应类型的基本数据类型的过程叫“拆箱”

在上面中给变量a赋值的时候就发生了装箱,而在参与计算的过程中就发生了拆箱,但是我们好像什么都没做,这句是自动拆装箱
下面我们再给一个例子
装箱

	int num = 25;
	Integer i = Integer.valueOf(num);
	Integer i = 25;

拆箱

	Integer i = new Integer(10);
		//unboxing
		int num = i;
		Float f = new Float(56.78);
		float fNum = f;

自动拆箱与自动装箱
Java为了简便拆箱与装箱的操作,提供了自动拆装箱的功能,这极大地方便了程序员们

public static void main(String[] args) {
    Integer a = Integer.valueOf(0);
    for (int i = 0; i < 100; i++) {
        a = Integer.valueOf(a.intValue() + i);
    }
}

我们不难发现,主要调用了两个方法,Integer.intValue() 和 Integer.valueOf( int i) 方法,拆箱的过程就是通过Integer 实体调用intValue()方法;装箱的过程就是调用了 Integer.valueOf(int i) 方法,帮你直接new了一个Integer对象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值