Java类包
类名冲突
Java允许创建相同名称的类,但是使用相同名称的类容易造成类名的冲突。
创建一个类:
public class Demo {
public static void main(String[] args) {
String a = "123";
}
}
此时可以创建一个与String名称完全相同的类:
public class Demo {
public static void main(String[] args) {
String a = "123";
}
}
class String{
}
此时上方就会报错,
这是因为下面的String类覆盖了原有的String类。
完整的类路径
完整类名
包名.类名
java.lang.String
java.util.List
import关键字
导入包
import java.lang.Math
java.lang
:包的名称
Math
:类的名称
创建Date类
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class Demo {
public static void main(String[] args) {
Date date = new Date();
List list = new ArrayList();
}
}
如果用到了很多的类,一个个写很麻烦,解决方案是:
import java.util.*;
public class Demo {
public static void main(String[] args) {
Date date = new Date();
List list = new ArrayList();
}
}
第一行的语句的含义是一次性导入java.util
包下的所有的类
除了util
包下有Date
类,sql包下也有Date类,同时使用时,如果直接写:
import java.util.Date;
import java.sql.Date;
public class Demo {
public static void main(String[] args) {
Date date = new Date();
}
}
会报错:
此时需要使用完整类名:
public class Demo {
public static void main(String[] args) {
java.util.Date date = new java.util.Date();
java.sql.Date date1 = new java.sql.Date(111);
}
}
导入静态成员
package Subway;
public class Demo {
public static void main(String[] args) {
System.out.println();
}
}
package Subway;
import static java.lang.System.out;
public class Demo {
public static void main(String[] args) {
out.println();
}
}
创建包
创建Plane
包,Plane
包下创建Takeoff
类:
package Plane;
public class TakeOff {
public void Start(){
System.out.println("上天");
}
}
创建Subway
包,Subway
包下创建Takeoff
类:
package Subway;
public class TakeOff {
public void Start(){
System.out.println("入地");
}
}
创建Demo类:
package Subway;
public class Demo {
public static void main(String[] args) {
TakeOff s = new TakeOff();
Plane.TakeOff p = new Plane.TakeOff();
p.Start();
s.Start();
}
}
输出:
上天
入地
可见:调用本包中的类的方法时,不需要写完整类型。也即,没有写完整类名时,默认调用本包中的方法;要调用其他包里的方法,需要写完整类名。
final常量、类、方法
一个变量经过final修饰以后变为一个常量,常量不容许再被修改。
final修饰类时,该类不能被继承;final修饰方法时,该方法不能被重写。
内部类
定义
再类体里面定义一个类,这个类就是内部类。
成员内部类
public class Demo {
class innerClass{//成员内部类
int y=0;
public innerClass(){
}
public void inf(){
System.out.println("内部类方法"+y);
}
}
}
在外部的成员方法中调用这个内部类,需要先创建一个内部类的对象:
public class Demo {
innerClass in = new innerClass();
public void outf(){
in.inf();
}
class innerClass{//成员内部类
int y=0;
public innerClass(){
}
public void inf(){
System.out.println("内部类方法"+y);
}
}
}
在main
方法中调用outf
方法:
public class Demo {
innerClass in = new innerClass();
public void outf(){
in.inf();
}
class innerClass{//成员内部类
int y=0;
public innerClass(){
}
public void inf(){
System.out.println("内部类方法"+y);
}
}
public static void main(String[] args) {
Demo d = new Demo();
d.outf();
}
}
输出:
内部类方法0
在main
方法中创建内部类对象:
Demo d = new Demo();
Demo.innerClass di = d.new innerClass();
public class Demo {
innerClass in = new innerClass();
public void outf(){
in.inf();
}
class innerClass{//成员内部类
int y=0;
public innerClass(){
}
public void inf(){
System.out.println("内部类方法"+y);
}
}
public static void main(String[] args) {
Demo d = new Demo();
Demo.innerClass di = d.new innerClass();
d.outf();
di.inf();
}
}
输出:
内部类方法0
内部类方法0
局部内部类
在成员方法中创建类,并创建它的构造方法:
public class Demo2 {
public void action(String x){
class innerClass {
public innerClass(String s){
s=x;
System.out.println(s);
}
}
}
}
如果要创建这个内部类的对象,需要借用接口:
首先需要将它返回出来:
public class Demo2 {
public innerClass action(String x){
class innerClass {
public innerClass(String s){
s=x;
System.out.println(s);
}
}
}
}
此时编译器会报错,因为在声明innerClass
之前,不存在这个类。此时就需要使用接口来解决这个问题。
public class Demo2 {
public outInterface action(String x){
class innerClass implements outInterface{
public innerClass(String s){
s=x;
System.out.println(s);
}
}
return new innerClass("随便返回一个参数");
}
public static void main(String[] args) {
Demo2 d = new Demo2();
d.action("局部内部类");
}
}
interface outInterface{//专门用来作为内部类向上转型的父接口
}
匿名内部类
先创建一个接口,在action方法中返回这个接口时,实例化这个类。
public class Demo3 {
public outInterface action(){
return new outInterface() {
private int i=0;
public int getValue(){
return i;
}
};
}
}
interface outInterface2{
}
此代码的效果与:
public class Demo4 {
public outInterface3 action(){
return new innerClass();
}
}
interface outInterface3{
}
class innerClass implements outInterface3{
private int i = 0;
public int getValue(){
return i;
}
}
是等效的。
静态内部类
静态内部类与成员内部类相似
public class Demo6 {
static class innerClass4{
}
}
如下代码,在静态内部类中调用非静态变量会报错:
public class Demo6 {
int x = 0;
static class innerClass4 {
void action(){
x=1;
}
}
}
静态类有一个特殊效果,就是它可以在内部创建main
方法:
public class Demo6 {
static int x = 0;
static class innerClass4 {
public static void main(String[] args) {
System.out.println("我是静态内部类。");
}
}
}
代码可以直接运行
内部类的继承
有一个内部类ClassB
class ClassA{
class ClassB{
}
}
如果想继承这个ClassB
class OutputInnerClass extends ClassA.ClassB{
}
继承一个内部类时,就必须添加一个带参数的构造方法,这个参数需要是外部类的对象。
public class Demo7 {
class ClassA{
}
public static void main(String[] args) {
}
}
class NewClass extends Demo7.ClassA{
public NewClass(Demo7 d){
d.super();
}
}