51.内部类(了解)面试
类内部的类就是内部类,能够无限层。数组
位置:把一个类定义到另外一个类中,那么内部的类就是内部类。this
注意:内部类不能直接建立spa
建立内部类的语法:3d
外部类.内部类 变量名 = new 外部类对象().new内部类对象()code
内部类的外部类的方法若是想要访问内部类的方法,必须建立内部类的对象,根据内部类的对象来访问。对象
(1)普通内部类blog
内部类的特色:本类或者本类方法中能够直接建立内部类的对象,经过内部类对象能够调用内部类的属性和方法;继承
内部类和外部类对象都不能直接访问彼此的属性和方法接口
内部类的方法能够访问外部类的属性和方法,外部类的方法不能直接访问内部类的属性和方法可是能够经过内部类对象间接访问
//建立一个外部类
class Outter{
String name;
public void printOutter(){
System.out.println("外部类方法!");
}
//建立一个内部类,内部类能够无限层
class Inner{
int age;
//内部类的方法能够访问外部类的方法,可是外部类的方法不能访问内部类的方法
public void printInner(){
//调用外部类方法(不要加this)
printOutter();
System.out.println("内部类方法!");
}
//内部类的方法能够访问外部类的属性,可是外部类的方法不能访问内部类的属性
public void introduceIn(){
System.out.println("内部类方法打印姓名:"+name+"年龄:"+age);
}
}
//本类之中能够直接建立内部类,可是内部类对象不能直接调用外部类的属性和方法
public void method(){
Inner i=new Inner();
i.age=10;
i.printInner();
i.introduceIn();
}
}
public class Test5{
public static void main(String[] args){
//建立一个内部类对象:外部类.内部类 变量名 = new 外部类对象().new内部类对象()
Outter.Inner p=new Outter().new Inner();
//内部类对象不能直接调用外部类的方法和属性
p.age=12;
p.printInner();
p.introduceIn();
//外部类对象不能直接调用内部类的属性和方法,可是能够间接调用
Outter o=new Outter();
o.name="pp";
o.method();
}
}
(2)匿名内部类(接口或者抽象类)
没有名字须要在接口或者抽象上实现的内部类
接口名 变量名=new 接口名(){实现接口的方法};这个大括号就至关于一个内部类,别忘了分号
另一种表现方式,new 接口名(){实现接口的方法}.方法名();
interface Dog{
public void speek();
}
public class Test{
public static void main(String[] args){
//接口名 变量名=new 接口名(){实现接口的方法};这个大括号就至关于一个内部类,别忘了分号
Dog p=new Dog(){
String name="二哈";
public void speek(){
System.out.println(name+"冲着你汪汪汪!");
}
//别忘了这里的分号
};
p.speek();
//另一种表现方式,new 接口名(){实现接口的方法}.方法名();
new Dog(){
public void speek(){
System.out.println("冲着你汪汪汪!");
}
}.speek();
}
}
abstract class Dog1{
//抽象类中能够设置属性
private String name;
public Dog1(String name){
this.name=name;
}
public void setName(String nm){
name=nm;
}
public String getName(){
return name;
}
public abstract void speek();
}
public class Test1{
public static void main(String[] args){
//接口名 变量名=new 接口名(){实现接口的方法};这个大括号就至关于一个内部类,别忘了分号
Dog1 p=new Dog1("二哈"){
public void speek(){
//调用封装方法获得私有属性
System.out.println(getName()+"冲着你汪汪汪!");
}
//别忘了这里的分号
};
p.speek();
//另一种表现方式,new 接口名(){实现接口的方法}.方法名();
new Dog1("泰迪"){
public void speek(){
System.out.println(getName()+"冲着你汪汪汪!");
}
}.speek();
}
}
52.访问权限修饰符
权限修饰符就是用来控制类属性,方法的访问的权限的标识
访问权限的修饰符一共有四种:private, 默认, protected, public
(1)访问权限修饰符修饰在类上:public修饰的类是能够随便访问,若是是默认修饰的同包能够访问,跨包不可访问
(包的知识点中已经讲过了,只有public的类不一样包能够导入包再访问类)
(2)访问权限修饰符修饰在方法和属性上:
修饰同一个类中的方法或者属性能够被直接或者间接访问
修饰的方法或者属性,在同包不一样类中能够被直接或间接访问
不一样包不一样类但为父子类的
无关类
类通常会用public修饰
属性通常用private修饰
方法通常用public,少数用protected、private修饰
53.Object类
Object是全部类的根类(默认隐藏地继承了objct类),全部的类都是直接或者间接的去继承Object类。
根类:最上层的类
超类:根类和父类之间的类
类 Object 是类层次结构的根类。每一个类都使用 Object 做为超类。全部对象(包括数组)都实现这个类的方法。
(1)toString方法
public String toString()
返回该对象的字符串表示。一般,toString
方法会返回一个“以文本方式表示”此对象的字符串。结果应是一个简明但易于读懂的信息表达式。建议全部子类都重写此方法。
Object
类的 toString
方法返回一个字符串,该字符串由类名(对象是该类的一个实例)、at 标记符“@
”和此对象哈希码的无符号十六进制表示组成。换句话说,该方法返回一个字符串,它的值等于:
getClass().getName() + '@' + Integer.toHexString(hashCode())
返回: 该对象的字符串表示形式。
toString方法在Object中的源码实现:
public String toString(){
return getClass().getName()+'@'+Integer.toHexString(hashCode())
}
getClass().getName() 得到toString的方法的类的类名
Integer.toHexString(hashCode()) 得到这个对象的hash值的16进制
hashCode方法 每个对象都有惟一的一个hash值,不一样的整数。
getClass方法 得到一个类的类对象
class Person{
}
public class Test2{
public static void main(String[] args){
Person p=new Person();
int h=p.hashCode();
System.out.println(h);
System.out.println(Integer.toHexString(h));
System.out.println(p.getClass());
System.out.println(p.getClass().getName());
}
}
(2)重写toString方法
class Person1{
String name;
String habit;
public void speek(){
System.out.println("你好!");
}
/*重写toString方法
public String toString(){
return getClass().getName()+'@'+Integer.toHexString(hashCode());
}
*/
public String toString(){
speek();
return "我是"+name+"个人爱好是"+habit;
}
}
public class Test3{
public static void main(String[] args){
Person1 p=new Person1();
p.name="小可爱";
p.habit="撩小哥哥";
//默认的调用了toString方法
System.out.println(p);
}
}
(3)finalize()
面试题:
final、finally、finalize的区别
final做用在类上表示最后一个类不可被继承,修饰在方法上方法不可被覆写,修饰在属性上属性和变量上不可修改,属性能够在建立的时候赋予初始值或者构造器中赋予初始值(每一个构造器都必须显示final这个属性的初始化)
(4)equals方法
==双等号
在Object中源码:
public boolean equals(Object obj){
return (this==objets);
}
基本数据类型比较的是值,各自有各自的默认值;
引用数据类型比较的是地址,默认值是null
(5)重写equals方法
class Child{
String fa;
String mo;
int age;
String face;
/*重写equals方法
public boolean equals(Object obj){
return(this==obj);
}
*/
//重写规则:两个孩子的父亲和母亲同样,年龄相等、长相同样的是一胎生的
public boolean equals(Object obj){
//建立一个返回类型做为判断标识
boolean flag=false;
//判断是否来自于子类
if(obj instanceof Child){
//将自动转成父类的子类对象再转回子类,方便调用子类中的属性
Child c=(Child)obj;
//字符串类型调用equals方法须要判断字符串不为默认值
if(this.fa==c.fa&&this.mo==c.mo&&this.age==c.age&&this.face!=null&&c.face!=null&&this.face.equals(c.face)){
flag=true;
}
}
return flag;
}
}
public class Test4{
public static void main(String[] args){
Child a=new Child();
Child b=new Child();
a.fa="dady";
a.mo="mama";
a.age=8;
a.face="beautiful";
b.fa="dady";
b.mo="mama";
b.age=8;
b.face="beautiful";
boolean x=a.equals(b);
System.out.println(x);
}
}