public |
protected |
(default) |
private |
|
---|---|---|---|---|
同一个类 | ✔ | ✔ | ✔ | ✔ |
同一个包 | ✔ | ✔ | ✔ | ✘ |
不同的包是子类 | ✔ | ✔ | ✘ | ✘ |
不同的包且不是子类 | ✔ | ✘ | ✘ | ✘ |
final
:final放在类前面修饰,表示final类,不能被继承,放在方法前面,表示这个方法不可以被该类的子类进行方法重写,用于修饰局部变量,只能赋值一次,后面不能对该变量进行修改,如果是基本数据类型,就是其值不能改变,如果是引用数据类型,就是其值(地址)不能发生改变,如果是放在成员变量之前修饰,那就是成员变量不能够更改,要么在成员变量定义时给定初值,要么将出现的所有的构造方法都需要对其成员变量进行赋值操作,只有一次。
成员内部类的使用方式如:
/*
成员内部类直接定义在外部类的里面,格式如:
public class Test{
public class InnerClass{
...
}
....
}
*/
public class A{
String username;
public A{
}
public String getUsername(){
return this.username;
}
public void setUsername(String username){
this.username=username;
}
public class B{
System.out.println("Hello InnerClassB");
}
public void Test(){
B b=new b();
b.username="hello";
}
}
内部类的访问方式有两种:
间接使用
:在创建外部类的时候,通过调用外部类的方法(方法内部包含了使用内部类的创建),就实现了内部类的创建和使用。
直接使用
:外部类.内部类 对象名称=new 外部类().new 内部类();
/*如上述所写代码*/
A.B test=new A().new B();
2.4局部变量,成员变量,外部类成员变量,父类成员变量同名时候的访问
在类的继承中,存在有成员变量,父类成员变量,局部变量变量名相同的问题,为了区分三个不同变量的使用,需要使用相应的关键字。
/*
父类A,子类B,方法test中都存在一个相同的变量username
*/
//父类
public class A{
String username;
}
//子类
public class B extends A{
String username;
public void Test(){
String username;
System.out.println(username);//访问方法体内部的局部变量username
System.out.println(this.username);//访问子类B中的成员变量username
System.out.println(super.username);//访问子类B的父类A中的成员变量username
}
}
同理,在内部类中也存在,成员变量,内部类成员变量,局部变量变量名相同的问题,为了区分三个不同变量的使用,需要使用相应的关键字。
/*
类(外部类)A,内部类B,方法Test中都存在一个相同的变量username
*/
public class A{
String username;
public class B{
String username;
public void Test(){
System.out.println(username);//访问方法体内部的局部变量
System.out.println(this.username)//访问内部类B中的成员变量
System.out.println(A.this.username)//访问内部类的外部类A的成员变量
}
}
}
总结
:需要明白this的关健字的含义,谁使用this就指向谁。
备注
:如果接口的实现类,或者父类的子类只使用一次,可以直接使用匿名内部类,从而省略了接口实现类或者是子类的定义。
匿名内部类的定义方法为:接口名称 变量名=new 接口名称(){重写接口中的所有的抽象方法};
//接口A
public interface A{
public abstract int getId();
}
//测试类
/*
直接使用了匿名内部类,没有使用接口的实现类
*/
public class Test{
public static void main(String args[]){
A a=new A(){
public int getId(){
return 1;
}
};
int id=a.getId();
System.out.println(id);
}
}
/*
否则需要接口的实现类
*/
public class B implements A{
public int getId(){
return 1;
}
}
//测试类
public class Test{
public static void main(String args[]){
A a=new B();
int id=a.getId();
System.out.println(id);
}
}
注意
匿名内部类在创建对象的时候只能出现一次,如果对象内部内容一样,也需要多次写。
区分以下匿名对象和匿名内部类:
匿名对象是省略了对象名称,匿名类是省略了类的名称,其中匿名对象new A()
,左边没有,表示匿名对象,而匿名内部类如前述所示,没有创建这个类。
每一个类,调用System.out.println(对象名),默认打印的是对象的地址值,如果不是地址值,就是重写了toString()方法。
Objects.euqals(s1,s2);比较两个对象是否相等,可以防止空指针异常。
==比较,如果是基本数据类型比较,就直接比较的是数值的大小,而如果是引用类型,比较的就是变量的地址值是否相等。
Object.equals(Object2);可以比较值得内容是否相等。
String s1="hello";
String s2="Hello";
char[] s=new char[]{'h','e','l','l','o'};
String s3=new String(s);
System.out.println(s1==s2);//false
System.out.println(s1==s3);//false
System.out.println(s2==s3);//false
System.out.println(s2.equals(s3));//false
System.out.println(s1.equals(s3));//true
System.out.println(s1.equals(s2));//false
System.out.println(Objects.equals(s1,s3));//true
2 Data类(表示日期和时间的类)
Date date=new Date();
System.out.println(date);
long Seconds=date.getTime();
SimpleDateFormate s=new SimpleDateFormate("yyyy-MM-dd HH:mm:ss");
Date time=s.parse("2020-04-06: 16:26:50");
String stime=s.format(date);
需要注意的地方:
Date类中的getTime()函数是将当前时间转换为毫秒值,是一个long型的整形数据,是与1970年1月1日0点0分0秒的毫秒值的差值。
SimpleDateFormat是一个格式化时间的类,可以将时间转换为想要的字符串形式(format),和将字符串解析为日期格式(parse)。