面向对象高级(三)
面向对象高级(三)
一、内部类
内部类:类中的五大成分之一(成员变量、方法、构造器、内部类、代码块),如果一个类定义在另一个类的内部,这个类就是内部类。
内部类有四种形式,分别是成员内部类、静态内部类、局部内部类、匿名内部类。
1.1 成员内部类
成员内部类就是类中的一个普通成员,类似于成员变量、成员方法。
1 |
|
创建对象格式:
1 |
|
总结一下内部类访问成员的特点
- 既可以访问内部类成员、也可以访问外部类成员
- 如果内部类成员和外部类成员同名,可以使用**
类名.this.成员
**区分
1.2 静态内部类
在成员内部类的前面加了一个static关键字。静态内部类属于外部类自己持有。
1 |
|
需要使用外部类的类名调用。
1 |
|
1.3 局部内部类
是定义在方法中的类,和局部变量一样,只能在方法中有效。
局部内部类的局限性很强,一般在开发中是不会使用的。
1.4 匿名内部类
匿名内部类是一种特殊的局部内部类;所谓匿名,指的是程序员不需要为这个类声明名字。
1 |
|
匿名内部类 本质上 时一个没有名字的子类对象、或者接口的实现类对象,
只有在调用方法时,当方法的形参是一个接口或者抽象类,为了简化代码书写,而直接传递匿名内部类对象给方法。
二、枚举
2.1 枚举类
1 |
|
其实枚举项就表示枚举类的对象,只是这些对象在定义枚举类时就预先写好了,以后就只能用这几个固定的对象。.
2.2 场景
枚举一般表示一组信息,然后作为参数进行传输。
我们现在有这么一个应用,用户进入应用时,需要让用户选择是女生、还是男生,然后系统会根据用户选择的是男生,还是女生推荐不同的信息给用户观看。
这里我们就可以先定义一个枚举类,用来表示男生、或者女生
1 |
|
再定义一个测试类,完成用户进入系统后的选择
1 |
|
最终再总结一下枚举的应用场景:枚举一般表示几个固定的值,然后作为参数进行传输。
三、泛型
3.1 泛型
在定义类、接口、方法时,同时声明了一个或者多个类型变量(如:
ArrayList集合的设计者在定义ArrayList集合时,就已经明确ArrayList集合时给别人装数据用的,但是别人用ArrayList集合时候,装什么类型的数据他不知道,所以就用一个<E>
表示元素的数据类型。
3.2 自定义泛型类
1 |
|
四、常用API
4.1 Object类
Object类是Java中所有类的祖宗类,因此,Java中所有类的对象都可以直接使用Object类中提供的一些方法。
toString():调用toString()方法可以返回对象的字符串表示形式
在Student类重写toString()方法,那么我们可以返回对象的属性值,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14public class Student{
private String name;
private int age;
public Student(String name, int age){
this.name=name;
this.age=age;
}
@Override
public String toString(){
return "Student{name=‘"+name+"’, age="+age+"}";
}
}euqals(Object o):判断此对象与参数对象是否”相等”
1
2
3
4
5
6
7
8
9
10
11public class Test{
public static void main(String[] args){
Student s1 = new Student("赵薇",23);
Student s2 = new Student("赵薇",23);
//equals本身也是比较对象的地址,和"=="没有区别
System.out.println(s1.equals(s2)); //false
//"=="比较对象的地址
System.out.println(s1==s2); //false
}
}但是如果我们在Student类中,把equals方法重写了,就按照对象的属性值进行比较
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26public class Student{
private String name;
private int age;
public Student(String name, int age){
this.name=name;
this.age=age;
}
@Override
public String toString(){
return "Student{name=‘"+name+"’, age="+age+"}";
}
//重写equals方法,按照对象的属性值进行比较
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
if (age != student.age) return false;
return name != null ? name.equals(student.name) : student.name == null;
}
}clone()方法:某一个对象调用这个方法,这个方法会复制一个一模一样的新对象,并返回。
想要调用clone()方法,必须让被克隆的类实现Cloneable接口。如我们准备克隆User类的对象,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35public class User implements Cloneable{
private String id; //编号
private String username; //用户名
private String password; //密码
private double[] scores; //分数
public User() {
}
public User(String id, String username, String password, double[] scores) {
this.id = id;
this.username = username;
this.password = password;
this.scores = scores;
}
//...get和set...方法自己加上
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
User u1 = new User(1,"zhangsan","wo666",new double[]{99.0,99.5});
//调用方法克隆得到一个新对象
User u2 = (User) u1.clone();
System.out.println(u2.getId());
System.out.println(u2.getUsername());
System.out.println(u2.getPassword());
System.out.println(u2.getScores());
}
}
}上面演示的克隆方式,是一种浅克隆的方法,浅克隆的意思:拷贝出来的对象封装的数据与原对象封装的数据一模一样(引用类型拷贝的是地址值)。
深拷贝:对象中基本类型的数据直接拷贝,对象中字符串数据拷贝的时地址,其他对象,不会拷贝地址,会创新新对象。
4.2 Objects类
提供了一些方法可以对任意对象进行操作。
4.3 基本类型包装类
Java中有一句很经典的话,万物皆对象。Java中的8种基本数据类型还不是对象,所以要把它们变成对象,变成对象之后,可以提供一些方法对数据进行操作。
创建包装类对象
1
2
3
4Integer a = new Integer(10);
Integer b = Integer.value(10);
Integer c = 10; //自动装箱
int d = c ;//自动拆箱包装类数据类型转换
把字符串转换成数值型数据:
public static int parseInt(String s)
把数值型数据转换成字符串:
public static String valueof(int a)