Java之包及内部类

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java之包及内部类相关的知识,希望对你有一定的参考价值。

1.包的概述

  包,其实就是文件夹。

  包的作用是对类进行分类管理。

  包的划分:按功能划分和按照模块划分。


2.包的定义及注意事项

  包的定义:package 包名;

  多级包名用.号隔开。

  注意事项:

    package语句必须是程序的第一条可执行的代码。

    package语句在一个Java文件中只能有一个。

    如果没有package,则默认表示无包名。

package cn;

public class HelloWorld {
	public static void main(String[] args){
		System.out.println("Hello World");
	}
}

  带包的编译和运行:

    手动式:

      a:编写一个带包的Java文件

      b:通过javac命令编译该Java源文件

      c:手动创建包名

      d:把b步骤的class文件放到c步骤的最底层包

      e:回到包根目录在同一目录的地方,然后运行

      f:带包运行 java cn.HelloWorld

    自动式:

      a:javac编译的时候带上-d即可

        javac -d . HelloWorld.java

      b:通过java命令执行,和手动式一样,带上包名

        java cn.HelloWorld


3.不同包下的类之间的访问

package cn;
/**
 * 求和
 */
public class Demo {
	public int sum(int a,int b){
		return a + b;
	}
}
package com;
/**
 * 测试 
 */
public class Test {
	public static void main(String[] args) {
		cn.Demo d = new cn.Demo();//这样太麻烦了
		System.out.println(d.sum(1, 2));
		
	}
}


4.导包

  导包概述:不同包下的类之间的访问,我们发现,每次使用不同包下的类的时候,都需要加包地全路径。好麻烦,这个时候,java就提供了导包的功能。

  导包格式:

    import 包名;

    注意:这种方式导入时导类的名称。

package cn;
/**
 * 求和
 */
public class Demo {
	public int sum(int a,int b){
		return a + b;
	}
}
package com;

import cn.Demo;

/**
 * 测试 
 */
public class Test {
	public static void main(String[] args) {
		Demo d = new Demo();
		System.out.println(d.sum(1, 2));
		
	}
}


5.package、import、class有没有顺序

 pcakge>import>class

  package:只能有一个

  import:可以有多个

  class:可以有多个,但是若class用public修饰,那么只能有一个


7.权限修饰符


public protected默认private
同一类中
同一包子类,其他类
不同包子类

不同包 其他类



8.类及其组成可以用的修饰符

 修饰符:

    权限修饰符:private、默认、protected、public

    状态修饰符:static、final

    抽象修饰符:abstract

  类:

    默认修饰符 public

    final 

    abstract

  成员变量:

    private 默认 protected public

    static final

  构造方法

    private 默认 protected public

  成员方法

    private 默认 protected public

    static final

    abstract


9.内部类概述及访问特点

  内部类概述:把类定义在其他类的内部,这个类就被称为内部类。

  内部类的访问特点:

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

    外部类要访问内部类的成员,必须创建对象。

package cn;
/**
 * 内部类概述:
 * 	把类定义在其他类的内部,这个类就被称为内部类
 * 	例如:在类A中定义了一个类B,类B就是内部类。
 * 内部类的访问特点:
 *  1.内部类可以直接访问外部类的成员,包括私有
 *  2.外部类要想访问内部类的成员,必须创建对象
 */
//外部类
class Outer{
	private int num = 10;
	//内部类
	class Inner{
		public void show(){
			System.out.println(num);
		}
	}
	
	public void method(){
		new Inner().show();
	}
		
}
public class InnerClassDemo {
	public static void main(String[] args) {
		
	}

}


10.内部类的位置

  按照内部类在类中定义的位置不同,可以分为如下两种格式:1)成员位置(成员内部类)2)局部位置(局部内部类)

  成员内部类:

    外界如何创建对象:外部类名.内部类名 对象名 = 外部类对象.内部类对象;

package cn;
/**
 * 内部类的位置
 * 	成员位置:在成员位置定义的内部类,被称为成员内部类
 *	局部位置:在局部位置定义的内部类,被称为局部内部类
 *
 * 	成员内部类:
 * 		如何直接访问内部类的成员?
 *      外部类名.内部类名 对象名 = 外部类对象.内部类对象;
 */
class Outer{
	private int num = 10;//成员变量
	//成员位置  在成员位置定义的内部类,被称为成员内部类
	class Inner{
		public void show(){
			System.out.println(num);
		}
	}
	
	public void method(){
		//局部位置 在局部位置定义的内部类,被称为局部内部类
		class Inner{
			
		}
		System.out.println("成员方法method");
	}
}
public class InnerClassDemo2 {
	public static void main(String[] args) {
		//我要访问Inner类的show()方法
		//外部类名.内部类名 对象名 = 外部类对象.内部类对象;
		Outer.Inner oi = new Outer().new Inner();
		oi.show();
	}

}



11.成员内部类

  一般来说,在实际开发中,不会在外部直接访问成员内部类。

package com;
//身体
class Body{
	//心脏
	class Heart{
		public void operator(){
			System.out.println("做心脏搭桥手术");
		}
	}
}
public class InnerClassDemo {
	public static void main(String[] args) {
		/**
		 * 这样是可以访问到Operator方法,但是,试问,每个人都可以对你进行心脏搭桥手术吗
		 * 如果这样的话,要么心脏搭桥手术和1+1一样简单,要么我们疯了
		 */
		
		Body.Heart  bh = new Body().new Heart();
		bh.operator();
	}
}
package com;
//身体
class Body{
	//心脏
	private class Heart{
		public void operator(){
			System.out.println("做心脏搭桥手术");
		}
	}
	
	//提供一个方法来校验
	public void test(String job){
		if(job.equals("心脏外科医生")){
			new Heart().operator();
		}
	}
}
public class InnerClassDemo {
	public static void main(String[] args) {
		Body body = new Body();
		body.test("心脏外科医生");
	}
}

  成员内部类的修饰符:

    private:是为了保证数据的安全性。

    static:为了让数据访问更方便

      被静态修饰的成员内部类只能访问外部类的静态成员。

      内部类被静态修饰后的方法,可以有静态方法和非静态方法。

package com;
class Outer{
	private int num = 10;
	private static int num2 = 100;
	//内部类用惊天修饰时因为内部类可以看成是外部类的成员
	public static class Inner{
		
		public void show(){
			System.out.println(num2);
		}
		
		public static void show2(){
			System.out.println(num2);
		}
	}
}
public class InnerClassDemo {
	public static void main(String[] args) {
		//成员内部类被静态修饰后的访问方式
		//格式:外部类名.内部类名 对象名 = new 外部类名.内部类名();
		Outer.Inner oi = new Outer.Inner();
		oi.show();
		oi.show2();
		
		//show2()的另一种调用方式
		Outer.Inner.show2();
	}
}
package cn;
/**
 * 分别输出30 20 10
 * 注意:
 * 	1.内部类和外部类没有继承关系
 *  2.通过外部类名限定this对象
 */
class Outer{
	public int num = 10;
	class Inner{
		public int num = 20;
		public void show(){
			int num = 30;
			System.out.println(num);
			System.out.println(this.num);
			System.out.println(Outer.this.num);
		}
	}
	
}
public class InnerClassTest {
	public static void main(String[] args) {
		Outer.Inner oi = new Outer().new Inner();
		oi.show();
	}

}


12.局部内部类

  局部内部类,可以直接访问外部类的成员。

  局部内部类,可以创建内部类对象,通过对象调用内部内方法,来使用局部内部类功能。

  局部内部类访问局部变量的注意事项:

    必须加final关键字

    why?因为局部变量会随着方法的调用完毕而消失,这个时候,局部对象并没有立刻从堆内存中消失,还要使用那个变量。为了让数据还能卖继续使用,就用final修饰,这样,在堆内存里面存储的其实就是一个常量值

package com;
/**
 * 局部内部类
 * 	可以直接访问外部类的成员
 * 	在局部位置,可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能
 * 
 *  局部内部类访问局部变量的注意事项?
 *   局部内部类访问局部变量必须使用final关键字修饰
 *   因为局部变量是随着方法的调用而存在,随着方法调用完毕而消失。而堆内存中的对象是不会立即消失,
 *   所以,我们用final关键字修饰局部变量。假如final修饰后,这个变量变成了常量。
 *   即使方法调用完毕,但是在内存中存储的是数据20。
 *   所以即使方法调用完毕,堆内存中的对象还没有立即被垃圾回收器回收。
 *   
 */
class Outer{
	private int num = 10;
	
	public void method(){
		//局部内部类访问局部变量必须使用final关键字修饰
		final int num2 = 20;
		class Inner{
			
			public void show(){
				//可以直接访问外部类的成员
				System.out.println(Outer.this.num);
				//局部内部类访问局部变量必须使用final关键字修饰
				System.out.println(num2);
			}
			
		}
		//在局部位置,可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能
		new Inner().show();
	}
}
public class InnerClassDemo {
	public static void main(String[] args) {
		Outer o = new Outer();
		o.method();
	}
}


13.匿名内部类

  匿名内部类:其实就是内部类的简化写法。

  前提:存在一个类或者接口,这里的类可以是具体类也可以是抽象类。

package cn;
/**
 * 匿名内部类:
 * 	就是内部类的简化写法。
 * 
 * 前提:存在一个类或者接口
 *  这里的类可以是具体类也可以是抽象类 
 *
 * 格式:
 * 	new 类名或者接口名(){
 * 		重写方法();
 * }
 * 本质是一个继承了该类或者实现了该接口子类的匿名对象。
 */
interface Inter{
	public void show();
	public void show2();
}
class Outer{
	public void method(){
		 new Inter(){
			@Override
			public void show() {
				System.out.println("show");
			}

			@Override
			public void show2() {
				System.out.println("show2");
			}
		 }.show();
		 new Inter(){

			@Override
			public void show() {
				System.out.println("show1");
				
			}

			@Override
			public void show2() {
				System.out.println("show2");
			}
			 
		 }.show2();
		//多态
		 Inter i = new Inter() {
			
			@Override
			public void show2() {
				System.out.println("show2");
			}
			
			@Override
			public void show() {
				System.out.println("show");
			}
		};
		i.show();
		 
	}
}
public class InnerClassDemo {
	public static void main(String[] args) {
		Outer o = new Outer();
		o.method();
		
	}

}


14.匿名内部类在实际开发中的使用

package com;
/**
 * 匿名内部类在实际开发中的使用 
 *
 */
interface Person{
	public void study();
}
class Student implements Person{

	@Override
	public void study() {
		System.out.println("学生学习");
	}
}
class PersonDemo{
	/**
	 * 接口名作为形式参数
	 * 其实这里需要的不是接口,而是接口的实现类
	 * @param p
	 */
	public void method(Person p){
		p.study();
	}
}
public class InnerClassTest {
	public static void main(String[] args) {
	        //测试
		PersonDemo pd = new PersonDemo();
		pd.method(new Student());
	}
}
package com;
/**
 * 匿名内部类在实际开发中的使用 
 *
 */
interface Person{
	public void study();
}
class Student implements Person{

	@Override
	public void study() {
		System.out.println("学生学习");
	}
}
class PersonDemo{
	/**
	 * 接口名作为形式参数
	 * 其实这里需要的不是接口,而是接口的实现类
	 * @param p
	 */
	public void method(Person p){
		p.study();
	}
}
public class InnerClassTest {
	public static void main(String[] args) {
		PersonDemo pd = new PersonDemo();
		pd.method(new Student());
		System.out.println("-------------");
		//匿名内部类在开发中的使用
		//匿名内部类的本质是继承类或者实现了接口的子类匿名对象
		pd.method(new Person(){
			@Override
			public void study() {
				System.out.println("老师学习");
				
			}
		});
	}

}

本文出自 “11831428” 博客,请务必保留此出处http://11841428.blog.51cto.com/11831428/1859057

以上是关于Java之包及内部类的主要内容,如果未能解决你的问题,请参考以下文章

java之包类库精选

Java基础之包和权限访问

java基础之包

10.JavaSE之包机制

nodejs之包教不包会

片段内部静态类和gradle问题