千锋逆战学习第20天
努力不一定成功,不努力一定失败
Day 20
3、静态内部类
不依赖外部类对象,可直接创建或通过类名访问,可声明静态成员
只能直接访问外部类的静态成员(实例成员需实例化外部类对象)
Outer.Inner inner=new Outer.Inner();
Outer.Inner.show();
package com.qf.day20.t1.statics;
public class TestAtaticInnerClass {
public static void main(String[] args) {
System.out.println(Outer.Inner.b);
Outer.Inner in=new Outer.Inner();
in.m2();
}
}
class Outer{
private static int a=10;
String s="hello";
//静态内部类
static class Inner{
static int b=20;
public void m2(){
System.out.println(a);
//System.out.println(Outer.s); //Error 静态不能直接访问非静态
System.out.println("Inner m2()");
}
}
}
4、局部内部类
定义在外部类方法中,作用范围和创建对象范围仅限于当前方法
局部内部类访问外部类当前方法中的局部变量时,因无法保障变量的生命周期与自身相同,变量必须修饰为final
package com.qf.day20.t2.local;
public class TestLocalClass {
public static void main(String[] args) {
Outer out=new Outer();
out.m1();
}
}
class Outer{
int a=10;
//外部类实例方法
public void m1(){
final int b=20;//局部变量
//b=88;//赋值
class Inner{//局部内部类
int c=30;
public void m2(){
System.out.println(Outer.this.a);//访问外部类的实例成员
System.out.println(this.c);//访问内部类的实例成员
//b=40;//(变量必须是final修饰的常量)
System.out.println(b);//局部内部类访问外部类的局部变量
System.out.println("Inner m2()");
}
}
Inner in=new Inner();
System.out.println(in.c);
in.m2();
}
}
限制类的使用范围
package com.qf.day20.t3.local;
public class TestLocallnnerClassForApply {
public static void main(String[] args) {
// 学校一年级开设新班(班主任)
//Teacher teacher=new BeginnerTeacher();//Eorror
Teacher t=School.getTeacher(1);
t.teach();
}
}
class School{
public static Teacher getTeacher(int classNo){//封装
//初级老师
class BeginnerTeacher extends Teacher{
public void teach(){
System.out.println("初级老师在上课");
}
}
//高级老师
class AdvancedTeacher extends Teacher{
public void teach(){
System.out.println("高级老师在上课");
}
}
Teacher curruntTeacher=null;//返回值
if(classNo%2!=0){
curruntTeacher=new BeginnerTeacher();
}else{
curruntTeacher=new AdvancedTeacher();
}
return curruntTeacher;
}
}
abstract class Teacher{
public abstract void teach();
}
5、匿名内部类
没有类名的局部内部类(一切特征都与局部内部类相同)
必须继承一个父类或实现一个接口
定义类、实现类、创建对象的语法合并,只能创建一个该类的对象
优点:减少代码量
缺点:可读性较差
package com.qf.day20.t4.anonymity;
public class Test {
public static void main(String[] args) {
// 学校一年级开设新班(班主任)
//Teacher teacher=new BeginnerTeacher();//Eorror
Teacher t=School.getTeacher(1);
t.teach();
}
}
class School{
public static Teacher getTeacher(int classNo){//封装
//初级老师
class BeginnerTeacher extends Teacher{
public void teach(){
System.out.println("初级老师在上课");
}
}
Teacher curruntTeacher=null;//返回值
if(classNo%2!=0){
curruntTeacher=new BeginnerTeacher();
}else{
//匿名内部类(创建了一个“老师”的子类对象,实现了teach方法)
curruntTeacher=new Teacher(){
public void teach(){
System.out.println("高级老师在上课");
}
};
}
return curruntTeacher;
}
}
abstract class Teacher{
public abstract void teach();
}
二、Object类
1、概念
超类、基类,所有类的直接或间接父类,位于继承数的最顶层
任何类,如没有书写extends显示继承某个类,都默认继承Object类,否则为间接继承
Object类中所定义的方法,是所有对象都具备的方法
Object类型可以存储任何对象
作为参数,可接受任何对象
作为返回值,可返回任何对象
2、getClass()方法
public final Class<?>getClass(){}
返回引用中存储的实际对象类型
应用:通常用于判断两个引用中实际存储对象类型是否一致
package com.qf.day20.t5.objects;
public class TestMethodForGetClass {
public static void main(String[] args) {
Animal[] as=new Animal[]{new Dog(),new Cat(),new Dog()};
//判断数组中两个对象的真实类型是否相同
System.out.println(as[0].getClass());//获得真实类型
System.out.println(as[1].getClass());//获得真实类型
System.out.println(as[0].getClass()==as[1].getClass());
System.out.println(as[0].getClass()==as[2].getClass());
}
}
class Animal{
}
class Dog extends Animal{
}
class Cat extends Animal{
}
3、hashCode()方法
public int hashCode(){}
返回该对象的十进制的哈希码值
哈希算法根据对象的地址或字符串或数字计算出来的int类型的数组
哈希码并不唯一,可保证相同对象返回相同哈希码,尽量保证不同对象返回不同哈希码`
package com.qf.day20.t5.objects;
public class TestMethodForHashCode {
public static void main(String[] args) {
Teacher t1=new Teacher();
Teacher t2=new Teacher();
Teacher t3=new Teacher();
System.out.println(t1.hashCode());
System.out.println(t2.hashCode());
System.out.println(t3.hashCode());
String s1="abc";
String s2="def";
String s3="ghi";
String s4="abc";
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
System.out.println(s3.hashCode());
System.out.println(s1.hashCode());
System.out.println(s4.hashCode());
//巧合:不同对象,巧合般的返回了相同的哈希码(小概率)
}
}
class Teacher{}
运行结果:
366712642
1829164700
2018699554
96354
99333
102312
96354
96354
4、toSring()方法
public String toString(){}
返回该对象的字符串表示(表现形式)
可根据程序要求覆盖该方法,如:展示对象各个属性值
package com.qf.day20.t5.objects;
public class TestMethodForString2 {
public static void main(String[] args) {
Worker worker=new Worker();
worker.name="tom";
worker.age=25;
worker.sex="male";
worker.salary=8000;
System.out.println(worker); //toString()方法是对象的字符串表示形式,常用于展示对象的各个属性
}
}
class Worker{
String name;
int age;
String sex;
double salary;
//父类提供的方法无法满足子类需求时,可在子类中声明和父类完全相同的方法进行覆盖
public String toString(){
return name+"\t"+age+"\t"+sex+"\t"+salary;
}
}
运行结果:
tom 25 male 8000.0
equals()方法
public boolean equals(Object obj){}
默认实现为(this==obj),比较两个对象地址是否相同
可进行覆盖,比较两个对象的内容是否相同
比较两个引用是否指向同一个对象
判断obj是否为null
判断两个引用指向的实际对象类型是否一致
强转类型转换
依次比较各个属性值是否相同
package com.qf.day20.t5.objects;
public class TestMethodForEquals {
public static void main(String[] args) {
Student s1=new Student("tom",20,"male",99D,"13999999999");
Student s4=new Student("tom",20,"male",99D,new String("13999999999"));
//字符串String类型equals == 结果不一样,字符串对Object类中的原有方法进行覆盖,比较内容
System.out.println(s1==s4);//比较地址(因为地址 不同,返回false)
System.out.println(s1.equals(s4));//比较地址(因为内容相同,返回true)
}
}
class Student{
String name;
int age;
String sex;
double score;
String phone;
public Student(String name, int age, String sex, double score,String phone) {
super();
this.name = name;
this.age = age;
this.sex = sex;
this.score = score;
this.phone=phone;
}
@Override
public boolean equals(Object obj) {//比较内容
//1、比较两个对象的地址是否相同
if(this==obj){
return true;
}
//2、确认对象不为null
if(obj==null){
return false;
}
//3、确认类型
if(this.getClass()!=obj.getClass()){
return false;
}
//4、转型(转型的前提类型肯定是Student)
Student stu=(Student) obj;
//5、比较内容
if(this.name.equals(stu.name)&&this.age==stu.age&&this.sex.equals(stu.sex)
&&this.score==stu.score&&this.phone.equals(stu.phone)){//字符串比较用equals
return true;
}
return false;
}
}
class MyObject{
public boolean equals(Object obj){
return(this==obj);//Object类中的默认实现方式
}
}
运行结果:
false
true
Chapter 09 内部类、Object、包装类、String
Key Point:
●Object类
●finalize类
●toString类
●equals类
●getClass类
●包装类
●三种类型(原始类型、包装类、字符串)与6种转换
●串池
习题:
2、(toString方法)写出下面代码的运行结果
class Student{
private int age;
private String name;
public Student(){}
public Student( String name,int age) {
super();
this.age = age;
this.name = name;
}
public String toString(){
return name+" "+age;
}
}
public class TestStudent {
public static void main(String[] args) {
Student stu1=new Student();
Student stu2=new Student(“Tom”,18);
System.out.println(stu1);
System.out.println(stu2);
}
}
null 0
Tom 18
3、(equals)写出下面程序的运行结果
public class TestEquals {
public static void main(String[] args) {
String str1=new String(“Hello”);
String str2=new String(“Hello”);
System.out.println(str1.equals(str2));
System.out.println(str1==str2);
}
}
true
false
4、(getClass)写出下面程序的运行结果
class Animal{}
class Dog extends Animal{}
public class TestGetClass {
public static void main(String[] args) {
Animal a1=new Dog();
Animal a2=new Animal();
System.out.println(a1 instanceof Animal);
System.out.println(a1.getClass()==a2.getClass());
}
}
true
false
5、(内部类)java中的内部类包括 ABCD
A.成员内部类
B.静态内部类
C.局部内部类
D.匿名内部类
E.公开内部类
F.抽象内部类
6.为Worker类增加equals和toString方法
package t6;
public class TestWorker {
public static void main(String[] args) {
Worker[] worker=new Worker[]{
new Worker("tom",30,"male",4000.0),
new Worker("tom",30,"male",4000.0)
};
System.out.println(worker[0].equals(worker[1]));
System.out.println(worker[0]);
}
}
class Worker{
String name;
int age;
String sex;
double salary;
public Worker(String name, int age, String sex, double salary) {
super();
this.name = name;
this.age = age;
this.sex = sex;
this.salary = salary;
}
public String toString() {
return "Worker [name=" + name + ", age=" + age + ", sex=" + sex + ", salary=" + salary + "]";
}
@Override
public boolean equals(Object obj) {
if(this==obj){
return true;
}
if(obj==null){
return false;
}
if(this.getClass()!=obj.getClass()){
return false;
}
Worker worker=(Worker)obj;
if(this.name.equals(worker.name)&&this.age==worker.age&&this.sex.equals(worker.sex)&&this.salary==worker.salary){
return true;
}
return false;
}
}
9、(局部内部类)有下列代码:
class OuterClass{
private int value1=100;
private static int value2=200;
public void method(int values3){
final int value4=400;
class InnerClass{
public void print(){
//1
}
}
}
}
问:下列哪些代码能做//1处编译通过?ACD
A.System.out.println(value1);
B.System.out.println(value2);
C.System.out.println(value3);
D.System.out.println(value4);
10、已知接口Light定义如下:
interface Light{
void shine();
}
//定义Lamp类:
class Lamp{
public void on(Light light){
light.shine();
}
}
//写一个类TestLamp,部分代码如下:
public class TestLamp {
public static void main(String[] args) {
Lamp lamp=new Lamp();
//1
//2
}
}
把TestLamp类补充完整,要求:
1)在//1处使用局部内部类技术,调用lamp的on方法要求输出“shine in red”
2)在//2处使用匿名内部类技术,调用lamp的on方法要求输出“shine in yellow”
Lamp currentLamp=null;
currentLamp=new Lamp(){
public void on(){
System.out.println(“shine in yellow”);
}
};
来源:CSDN
作者:Y_L_Lee
链接:https://blog.csdn.net/Y_L_Lee/article/details/104550496