- 内部类(了解)

类内部的类就是内部类。
位置:把一个类定义到另一个类中,那么内部的类就是内部类。
注意:内部类不能直接创建
创建内部类的语法:
外部类.内部类 变量名 = new 外部类对象.new内部类对象
内部类的外部类的方法如果想要访问内部类的方法,必须创建内部类的对象,根据内部类的对象来访问。
内部类的编译后的class

-
- 普通内部类
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| class Outter{ int num; public void outMethod(){ System.out.println("我是外部的类的方法"); } class Inner{ int innerNum; public void inMethod(){ System.out.println("我是内部的类的方法"); } } } public class TestInner{ public static void main(String\[\] args){ //创建内部类的对象 外部类.内部类 变量名 = new 外部类对象.new内部类对象 Outter.Inner inner = new Outter().new Inner(); inner.innerNum = 13; inner.inMethod(); } } |
内部类的特点:
-
本类可以直接创建内部类的对象
-
内部类的方法可以访问外部类的属性和方法
-
- 匿名内部类
什么是匿名类:没有名字的类,这种类需要在接口或者抽象类上实现。
接口匿名内部类
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Interface Teacher{ public void teach(); } public class TestInner3{ public static void main(String\[\] args){ //创建的不是接口本身,new Teach()后面的大括号就是一个匿名类(实现了Teacher接口) Teacher jt1 = new Teacher(){ public void teach(){ System.out.println("我是匿名内部类的方法"); } }; jt1.teach(); new Teacher(){ public void teach(){ System.out.println("我是匿名内部类的方法1"); } }.teach(); } } |
抽象类匿名内部类
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| abstract class Teacher{ private String name; public Teacher(String name){ this.name = name; } public String getName(){ return name; } public abstract void teach(); } public class TestInner4{ public static void main(String\[\] args){ //创建的不是接口本身,new Teach()后面的大括号就是一个匿名类(实现了Teacher接口) Teacher jt1 = new Teacher("亮哥"){ public void teach(){ System.out.println(getName()+"正在教课"); } }; jt1.teach(); } } |
| 内部类对象如果要访问外部类的私有属性,需要提供公共的get方法通过调用get方法来获取外部类私有属性的值。 |
- 访问权限的修饰符
权限修饰符就是用来控制类属性,方法的访问的权限的标识
访问权限的修饰符一共有四种:private, 默认, protected, public

-
- 权限修饰符在类上
如果类有public是可以随便的访问,如果默认的话同包内能访问,跨包不能访问。

-
- 权限修饰符在属性或者方法上

权限修饰符在属性或者方法上的控制
同一个类的代码示例
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| public class ModiferTest2{ public void publicMethod(){ System.out.println("我是public方法"); } protected void protectedMethod(){ System.out.println("我是protected方法"); } void defaultMethod(){ System.out.println("我是默认方法"); } private void privateMethod(){ System.out.println("我是private方法"); } public static void main(String\[\] args){ ModiferTest2 m = new ModiferTest2(); m.privateMethod(); m.protectedMethod(); m.defaultMethod(); m.privateMethod(); } } |
两个类在同一个包中

不同包但是又父子类关系的两个类

无关类

我们通常情况:类我们一般设置成public的,属性一般都是private, 方法一般都是public的,也有少数使用(protect,private)
- Object

Object是所有类的根类,所有的类都是直接或者间接的去继承Object类(基类)。
根类:最上层的类
超类:根类和父类之间的类

类 Object 是类层次结构的根类。每个类都使用 Object 作为超类。所有对象(包括数组)都实现这个类的方法。
我们要学习的Object里面的方法

-
- toString
返回该对象的字符串表示。通常,toString 方法会返回一个"以文本方式表示"此对象的字符串。结果应是一个简明但易于读懂的信息表达式。建议所有子类都重写此方法。
如果我们打印一个对象的时候,实际上是打印这个对象调用toString的返回值。

toString在Object中的源码的实现

getClass().getName():获得调用toString的方法的类的类名
Integer.toHexString(hashCode()):获得这个对象的hash值的16进制
-
- toString 的重写
|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| class Student{ int sNo; String name; int age; public void learn(){ System.out.println(name+"在学习"); } /** toString的重写 */ public String toString(){ return "学号:"+sNo+" 名字:"+name+" 年龄:"+age; } } public class ObjectTest3{ public static void main(String\[\] args){ Student s = new Student(); s.sNo = 1; s.name = "亮哥"; s.age = 10; //隐藏的调用了toString System.out.println(s); } } |
-
- hashCode方法
hashCode也是Object中的一个方法
由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。每一个对象都有一个唯一的hash值

|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| class Student{ int sNo; String name; int age; public void learn(){ System.out.println(name+"在学习"); } } public class ObjectTest1{ public static void main(String\[\] args){ Student s = new Student(); //隐藏的调用了toString /* System.out.println(s); System.out.println(s.toString()); */ //获得这个对象的hash值 int hv = s.hashCode(); System.out.println("十进制:"+hv); //获得hash值的16进制 String hvh = Integer.toHexString(hv); System.out.println("十六进制:"+hvh); System.out.println("-------------------------------"); s = new Student(); hv = s.hashCode(); System.out.println("十进制:"+hv); //获得hash值的16进制 hvh = Integer.toHexString(hv); System.out.println("十六进制:"+hvh); } } |
-
- getClass ()
获得一个类的类对象。
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| public class ObjectTest2{ public static void main(String\[\] args)throws Exception{ Student s = new Student(); //调用从父类里面继承下来的getClass()方法获得类的类对象 Class c = s.getClass(); System.out.println(c.getName()); } } |
-
- finalize()
用于垃圾回收,我们不用手动的去调用,由jvm来调用,
当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
面试题:
final,finally(处理程序异常时使用的后面讲),finalize的区别?
-
- equals
==:
- 基本数据类型:比较的是值
- 引用数据类型:比较的是地址
Student s1=new Student();
Student s2=new Student();
//不相等 没有重写equals Object
S1.equals(s2);
基本数据类型的内存结构 == 比较的是值, 基本数据类型是有自己的默认值的。

引用数据类型 == 比较的是地址, 引用数据类型默认值是null

Object的equals实现

-
- equals重写
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| class Student{ int sNo; String name; int age; public void learn(){ System.out.println(name+"在学习"); } /** toString的重写 */ public String toString(){ return "学号:"+sNo+" 名字:"+name+" 年龄:"+age; } //我们认为sNo ,name, age相等就是学生相等 public boolean equals(Object obj) { //判断的标识 boolean flag = false; if(obj instanceof Student){ //把obj转换成子类的真身 Student s = (Student)obj; if(this.sNo == s.sNo && this.age == s.age && this.name != null && s.name != null && this.name.equals(s.name)){ flag = true; } } return flag; } } public class ObjectTest4{ public static void main(String\[\] args){ /* int i = 10; int j = 10; System.out.println(i == j); */ Student s = new Student(); s.sNo = 1; s.name = "亮哥"; s.age = 10; Student s1 = new Student(); s1.sNo = 1; s1.name = "亮哥"; s1.age = 10; //System.out.println(s == s1); //boolean equals(Object obj) boolean e = s.equals(s1); System.out.println(e); } } |