JAVA学习五:面向对象高级(2)

1.11 Object类
Object类是所有类的父类(基类),如果一个类没有明确的继承某一个具体的类,则将默认继承Object类。
例如我们定义一个类:
public class Person{}
其实它被使用时是这样的
public class Person extends Object{}

Object的多态
使用Object可以接收任意的引用数据类型
String s = “abc”;
say(s);//可以将String类型传入Object的形式参数,这就是Object的多态。
public static void say(Object o){
System.out.print(o);
}

1.12API的使用

Ctrl+鼠标左键查看类的源码

1.13toString
所有类建议重写Object中的toString方法。此方法的作用:返回对象的字符串表示形式。
Object的toString方法指返回对象的内存地址。

而重写toString可以通过文字更详细的描述你对象中的信息。如
public String toString(){
return “这是一个人,这个人的名字是:”+this.name;
}
快捷键shift+alt+s — Generate toString()勾选上想要添加的属性。

1.14equals
拿两个对象进行比较。返回boolean值
Object类有equals方法,但是也是==判断。
==比较的是地址,相当于引用数据类型的比较。
所以需要重写equals来比较对象。
equals方法重写时的五个特性:
自反性:对于任何非空的参考值x,x.equals(x)应该返回true。
对称性:对于任何非空引用值x和y,x.equals(y)应该返回true当且仅当y.equals(x)回报true。
传递性:对于任何非空引用值x,y,z如果x.equals(y)回报true和y.equals(z)返回true,然后x.equals(z)返回true。
一致性:对于任何非空引用值x和y,多次调用x.equals(y)始终返回true或返回false,前期是未修改对象上的equals比较重使用的信息。
非空性:对于任何非空的参考值x,x.equals(null)应该返回false。

代码:
public boolean equals(Object o){
if(this == o){//先比较内存地址
return true;
}
if(o == null){//再判断传进来的是否是空
return false;
}
if(o instanceof Person){//判断对象类型是否相同
Person p2 = (Person) o;//把o强转成同类型的子类
if(this.name.equals(p2.name) && this.age == p2.age){//判断属性是相同
return true;
}else{
return false;
}
}else{
return false;
}
}
//代码简化:因为只有一个if会进入true路线,所以其他的else都可以省略,当未进入if(o instanceof Person)线时直接往下走,全部return false。
//快捷键:Shift Alt s进入Generate hashCode() and equals

1.15内部类
概念
在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类被称为内部类。
广义上分为四种:
1、成员内部类
2、局部内部类
3、匿名内部类
4、静态内部类

成员内部类
最普通的内部类,它的定义为位于另一个类的内部,如下:
public class Outer{
private int x;

class Inner{//成员内部类写在成员属性的位置
内部类里面的写法与外部类并无区别
而且因为是非静态的,需要对象创建时才能使用内部类。
而成员内部类可以无条件访问外部类的所有成员属性和成员方法,包括private成员和静态成员。如果要访问外部类的同名成员,需要以下面的形式进行访问:
外部类.this.成员变量
外部类.this.成员方法
public void say(){
}
}
}

如何创建内部类的对象
Outer o = new Outer();
Outer.Inner i = o.new Inner();
i.say();

局部内部类
定义在方法中,类似代码:
public static void main(){
class Person{
public void say(){
System.out.print();
}
}
}
Person p = new Person();
p.say();
使用场景:
当需要实现接口的功能,但是这个接口没有子类时,可以在方法内部创建一个局部内部类实现这个接口,(这个类只使用一次时),这样就可以实现这个接口的功能。

匿名内部类
没有名字,所以创建方式有点奇怪,格式如下:
new 父类构造器(参数列表)|实现接口 {}
Person是接口
Person p = new Person(){
public void say(){
System.out.print;
}
};//创建了一个Person的实现类
注意事项:
1使用匿名内部类时必须继承一个类或者一个接口,但是两者不可兼得,同时只能继承一个类或者实现一个接口。
2.匿名内部类中是不能存在任何的静态成员变量和静态方法的。
3.匿名内部类中是不能定义构造函数的。
4.匿名内部类为局部内部类,所以局部内部类的所有限制同样对匿名内不了了有效。
5.匿名内部类不能是抽象的。它必须实现要继承的类或接口的所有方法。
6.只能访问final型的局部变量。
为什么局部内部类只能访问final型的局部变量。

final int a = 10;
class PersonImp implements Person{//这是一个局部内部类
public void say(){
System.out.print(a);
}
}
class文件编译时,class PersonImp内部并没有a=10,所以它会重新在内部备份一个a=10,当外部改变时内部并不会改变,这样就形成了逻辑错误,所以java直接将规则限制为只可以使用final常量。

面试回答:因为我们内部类会被单独编译成一个字节码文件,为了保证这个单独文件中的备份的变量与外部的变量值绝对是一致的,那么这时候系统从规则上限制了这个变量是不可更改的。

静态内部类

静态内部类是不需要依赖于外部类对象的。这点和静态成员属性有点类似,并且它不能使用外部类的非static成员变量或方法。

public class Book{
static class Info{
public void say(){}
}
}

在其他类中调用Info类
Book.Info info = new Book.Info();
这样创建了一个静态内部类的对象。
内部类的对象创建时,外部类的对象还未创建,所以它这时就无法使用非静态的外部类的成员变量或方法。

1.16包装类

概述
在Java中有一个设计的原则“一切皆对象”,那么这样一来Java中的一些基本的数据类型,就完全不符合于
这种设计思想,因为Java中的八种基本数据类型并不是引用数据类型,所以Java中为了解决这样的问题,
引入了八种基本数据类型的包装类。

序号 基本数据类型 包装类
1 int Integer
2 char Character
3 float Float
4 double Double
5 boolean Boolean
6 byte Byte
7 short Short
8 long Long
以上的八种包装类,可以将基本数据类型按照类的形式进行操作。
但是,以上的八种包装类也是分为两种大的类型的:
· Number:Integer、Short、Long、Double、Float、Byte都是Number的子类表示是一个
数字。
· Object:Character、Boolean都是Object的直接子类。

装箱和拆箱操作
以下以Integer和Float为例进行操作
将一个基本数据类型变为包装类,那么这样的操作称为装箱操作。
将一个包装类变为一个基本数据类型,这样的操作称为拆箱操作,
因为所有的数值型的包装类都是Number的子类,Number的类中定义了如下的操作方法,以下的全部方法都
是进行拆箱的操作。

序号 方法 描述
1 public byte byteValue() 用于Byte->byte
2 public abstract double doubleValue() 用于Double->double
3 public abstract float floatValue() 用于Float->float
4 public abstract int intValue() 用于Integer->int
5 public abstract long longValue() 用于Long->long
6 public short shortValue() 用于Short->short

装箱操作:
在JDK1.4之前 ,如果要想装箱,直接使用各个包装类的构造方法即可,例如:
int temp = 10 ; // 基本数据类型
Integer x = new Integer(temp) ; // 将基本数据类型变为包装类
在JDK1.5,Java新增了自动装箱和自动拆箱,而且可以直接通过包装类进行四则运算和自增自建操作。例
如:
 Float f = 10.3f ; // 自动装箱
float x = f ; // 自动拆箱
System.out.println(f * f) ; // 直接利用包装类完成
System.out.println(x * x) ; // 直接利用包装类完成

字符串转换
使用包装类还有一个很优秀的地方在于:可以将一个字符串变为指定的基本数据类型,此点一般在接收输入
数据上使用较多。
在Integer类中提供了以下的操作方法:
public static int parseInt(String s) :将String变为int型数据
在Float类中提供了以下的操作方法:
public static float parseFloat(String s) :将String变为Float
在Boolean 类中提供了以下操作方法:
  public static boolean parseBoolean(String s) :将String变为boolean

1.17可变参数
一个方法中定义完了参数,则在调用的时候必须传入与其一一对应的参数,但是在JDK 1.5之后提供了新的
功能,可以根据需要自动传入任意个数的参数。
语法:
返回值类型 方法名称(数据类型…参数名称){
//参数在方法内部 , 以数组的形式来接收
}
注意:
可变参数只能出现在参数列表的最后。

1.18递归
递归,在数学与计算机科学中,是指在方法的定义中使用方法自身。也就是说,递归算法是一种直接或者间
接调用自身方法的算法。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值