一.object类

1.概述

类object是类层次结构的根类,每个类都使用object作为超类,所有对象(包括数组)都实现这个类的方法。

2.应用

1)public int hashCode()返回该对象的哈希码值。哈希码值在底层通过哈希表进行的一个哈希算法算出来的,哈希码值不是实际地址值,可以理解为地址值

2)public final Class getClass()返回此 Object 的运行时类。

3)Class类中有一个getName():

public String getName()以 String 的形式返回此 Class(类) 对象所表示的实体名称。

二.形式参数和返回值类型的研究

1.形式参数为基本数据类型

基本数据类型,它对实际参数没有影响。

2.形式参数为引用类型

1)类:此时需要的是该类的对象,先对用到的类进行实例化,然后

方法所在的类的对象。方法名(引用类型的类的对象)

class Student{
public void show(){
System.out.println("Good Good Study,Day Day Up");
}
}
 
class Demo{
public void method(Student s){//类作为形参进行传递,此时需要实际参数就是该类对象
s.show();
}
}
//测试类
public class StudentDemo {
public static void main(String[] args) {
//1.需求:调用Demo中的method()方法
Demo d = new Demo() ;
类作为形参进行传递,此时需要实际参数就是该类对象
Student s = new Student() ;
d.method(s) ;
//2.匿名对象的方式
new Demo().method(new Student()) ;
}
}

2)接口:接口作为形式参数,不能实例化,需要先创建接口的子实现类,然后接口指向子类,形成接口对象,最后再引用成员方法。

interface Love{
public abstract void love();
}
class PersonDemo{
public void love(Love l){//接口作为形式参数:接口不能实例化
l.love();
}
}
//定义一个接口的子实现类
class Student4 implements Love{
 
@Override
public void love() {
System.out.println("学生爱java,爱游戏,爱生活");
}
}
//需求:
public class PersonTest {
public static void main(String[] args) {
//需求:需要调用PersonDemo中love():如何操作
//需要创建该接口的子实现类
//1创建PersonDemo类的对象
PersonDemo pd = new PersonDemo() ;
//需要使用接口多态的形式进行实例化:接口多态(开发中经常用到的)
Love l = new Student4() ;
l.love();
pd.love(l)?
//2.匿名对象的方式
new PersonDemo().love(new Student4());
}
}

3)抽象类:作为形式参数,抽象类不能实例化,需要先创建子实现类,然后父类指向子类,形成父类对象,最后再引用成员方法。

abstract class Person{
public void show(){
System.out.println("爱生活,爱Java...");
}
}
 
//需要创建该抽象类的子类对象
class Student3 extends Person{
}
 
class TeacherDemo2{
public void method(Person p){//参数类型:引用类型 :抽象类:抽象类不能直接实例化!
p.show() ;
}
}
 
//测试类
public class TeacherTest {
public static void main(String[] args) {
//需要调用TeacherDemo中的method()方法
//创建TeacherDemo类的对象
TeacherDemo2 td = new TeacherDemo2() ;
// Person p = new Person() ;//不能直接实例化:instance
//抽象类的多态形式
Person p = new Student3(); //属于抽象类多态!
td.method(p) ;
}
}

3.返回值类型为基本数据类型  return a+b;

4.返回值类型为引用类型

1)类:返回值类型:此时是一个具体的类,返回的就是该类的对象return s;

先创造成员方法所在类的对象,然后拿这个对象引用成员方法,等于 返回值类型和它的对象。最终结果是返回值的对象。方法名();

Student s = sd.getStudent();
 
class Student2{
public void show(){
System.out.println("Good Good Study,Day Day Up");
}
}
 
class StudentDemo2{
public Student2 getStudent2(){
//返回值类型:此时是一个具体的类,返回的就是该类的对象
// Student2 s = new Student2() ;
// return s ;
return new Student2(); //匿名对象的方式
}
}
 
//测试类
public class StudentTest {
public static void main(String[] args) {
//需要调用StudentDemo2中的getStudent2()方法
//首相,创建StudentDemo2的对象
StudentDemo2 sd = new StudentDemo2() ;
Student2 s= sd.getStudent2() ;//Student2 s = new Student2();
          s.show();
 
System.out.println(s);
//使用匿名对象的方式:一步走:链式编程!
// new StudentDemo2().getStudent2().show();
}
}

2)接口

先创造接口的子实现类,然后创造成员方法所在的类的对象,再拿这个对象引用成员方法,等于返回值类型和它的对象。最终结果是返回值的对象。方法名();

interface Love2{
public abstract void love() ;
}
 
class PersonDemo2{
public Love2 getLove(){
//分布走
// Love2 l = new Student5();//接口多态
// return l ;
return new Student5();
}
}
 
//创建该接口的子实现类
class Student5 implements Love2{
 
@Override
public void love() {
System.out.println("学生爱生活,爱java");
}
}
 
//测试类
public class PersonTest2 {
public static void main(String[] args) {
//调用PersonDemo2中的getLove()方法
PersonDemo2 pd = new PersonDemo2() ;
//接口多态,创建子实现类对象
Love2 l = pd.getLove() ; //pd.getLov() = new Student5();
l.love() ;
//匿名对象
new PersonDemo2().getLove().love() ;
}
}

3)抽象类:先创造抽象类的子类,然后创造成员方法所在的类的对象,再拿这个对象引用成员方法,等于 返回值类型和它的对象。最终结果是返回值的对象。方法名();

abstract class Teacher{
public void show(){
System.out.println("今天天气不是很热...");
}
}
 
//创建了一个该抽象类的子类
class BasicTeacher extends Teacher{
}
 
//抽象类作为一个返回值类型的做法
class Demo2{
public Teacher getTeacher(){//返回值类型是一个抽象类
// return new Teacher() ;//Teacher是抽象类
// Teacher t = new BasicTeacher();//抽象类的多态的形式
// return t ;
return new BasicTeacher();
}
}
//测试类:
public class TeacherDemo {
public static void main(String[] args) {
//需求:Demo2中的getTeacher()方法
Demo2 d = new Demo2() ;
Teacher t = d.getTeacher() ;//d.getTeacher()  隐藏了:return new BasicTeacher() ;
 Teacher t = new BasicTeacher();//抽象类的多态的形式
t.show() ;
}
}

三.内部类

1.定义

把一个类定义到其他类中,把这个类称为内部类

在A中定义一个B类,把B类叫做A类的内部类,A类叫做B类的外部类。

2.特点

内部类可以直接访问外部类的成员,包括私有。

外部类的成员访问内部类的成员,不能直接访问,需要创建内部类对象,使用对象去调用内部类的成员方法。

3.分类

成员内部类:在类中的成员位置

局部内部类;在局部位置

class Outer2{
private int num = 10 ;
//成员内部类
// class Inner{
// 
// }
public void method(){
//局部位置
//局部内部类
class Inner{
}
}
}
public class InnerClassDemo2 {
public static void main(String[] args) {
}
}

4.访问内部类成员

外部类名.内部类名 对象名=外部类对象.内部类对象;

class Outer3{
private int num = 10 ;
//成员内部类
class Inner3{
//成员内部类的成员方法
public void show(){
System.out.println("今天天气不错...");
}
}
}
 
//测试类
public class InnerClassDemo3 {
public static void main(String[] args) {
//需要去访问show()方法
// Inner3 i = new Inner3() ;
// i.show() ;
// 外部类名.内部类名 对象名 = 外部类对象.内部类对象;
Outer3.Inner3 oi = new Outer3().new Inner3();
oi.show() ;
}
}

5.修饰符

Private:修饰内部类,可以保证数据的安全性;

Static:方便数据的访问

静态的内部类访问外部数据,外部数据必须是静态的;

对于静态的外部成员访问里面的方式,

外部类名.内部类名 对象名 = new 外部类名.内部类名();

Outer4.Inner4 oi = new Outer4.Inner4();

5.关于局部内部类的面试题

局部内部类访问局部变量,会有什么现象?为什么?(jdk1.8以下)

那么局部变量必须被final修饰!为什么要用final修饰,局部变量随着方法调用而存在,随着方法的调用完毕而消失,堆内存中的对象不会立即消失,等待GC垃圾回收线程空闲的时候回收掉,

告诉我们GC垃圾回收器,内部类正在访问整数据,正字使用(需要定义为自定义常量,而是一个常量20)

class Outer5{
private int num = 10 ;
public void method(){
final int num2 = 20 ;//局部变量 (重点的细节!)
//定义局部内部类
class Inner5{
public void show(){
System.out.println(num);
System.out.println(num2);
}
}
//创建外部类对象
Inner5 i = new Inner5() ;
i.show() ;
}
}

6.内部类没有继承关系,不能使用super(),要想访问外部类的对象则用 外部类名.this.成员变量 来限定

(Outer.this.num);

7.匿名内部类

1)内部类的简化格式:

New 类或接口{

重写写或实现一些方法

} 类可以是抽象类也可以是具体类

2)本质 继承了该类或者实现该接口的子类匿名对象

8.例题

1)无参情况

interface Inter{
public abstract void show();
public abstract void show2();
}
//外部类
class Outer6{
//成员方法
public void method(){
//匿名内部类:
 
Inter i = new Inter() {//相当与接口的子实现类:接口多态的形式
@Override
public void show2() {
System.out.println("show2 inter");
}
@Override
public void show() {
System.out.println("show inter");
}
};
i.show();
i.show2();
}
}
//测试类
public class InnerClassDemo6 {
public static void main(String[] args) {
//调用show2(),show1()方法如何操作
Outer6 o = new Outer6() ;
o.method();
}
}

2)有参情况,接口作为形式参数

interface Person{
public abstract void study() ;
}
class PersonDemo{
public void method(Person p){
p.study();
}
}
//子实现类
class Student implements Person{
 
@Override
public void study() {
System.out.println("学习爱学习,爱生活");
}
}
//测试类
public class InnerClassTest2 {
public static void main(String[] args) {
//需求:调用PersonDemo中的method()方法
//需要创建接口的子实现类
//1)创建PersonDemo类的对象
PersonDemo pd = new PersonDemo() ;
//接口多态的方式:通过子实现类对象进行实例化
Person p = new Student() ;
pd.method(p) ;
System.out.println("-------------------");
//匿名内部类:方式2:常用!
//本质:是继承类该类或者是实现了该接口的子类的匿名对象
PersonDemo pd2 = new PersonDemo() ;
pd2.method(new Person() {//匿名内部类的方式!
@Override
public void study() {
System.out.println("学习爱学习,爱生活");
}
});
}
}