java篇 类的基本概念0x01:包与类

package(包)

为了避免类在一起混乱,可以把类放在文件夹里。这时就需要用 package 语句告诉 java 这个类在哪个 package 里。package 语句要和源文件的目录完全对应,大小写要一致。(就像public class要和文件名一致)

  • 不一样的话,比如 package com.test,但实际目录却为org.abc,就会在 package com.test下标记红线报错,但测试过(单一文件不涉及导入其他类的情况)并不影响编译运行。
  • 注意:如果是package com.test,那么源代码就只应该放到com\test下,而不是放到com\test\xxx下都可以。如果想放到com\test\xxx下,那么就package com.test.xxx

一般来说,类都会在包里,而不会直接放在根目录(src)下。
而且如果一个类(比如叫 TestClass)放到了默认的根目录(src)下,而没有放到一个包中,你想在别的包中的类里引用这个类(TestClass),你都无法import导入,也无法使用类的全限定名(因为没有包名)来引用这个类。(非得引用这个类,需要用到反射机制,这就很繁琐了,所以不要把问题复杂化,所有的类都应该放到某个包中)

  • 不同的包里可以有相同名字的类;
  • 一个类只能有一个 package 语句;
  • 如果有 package 语句,则必须是类的第一行有效代码。

IDEA 中目录结构

src
 |
 |--- com.phone
         |
         |--- parts

com.phone实际上是com\phone\,只是 IDEA 做了优化,但实际上不是一个目录,而是两个(/层)目录。com下面是phonephone下面是 parts


在包中使用类

这里假设的是所有代码文件都是带 package 语句,并且都放到了与package 语句描述相符的文件路径下。

当使用另一个包里的类时,需要带上包名。

  • 因为不同包是可以有相同类名的,所以引用一个类,需要明确指出这个类是哪个包里的类。

java 的设定是,一个类只能发现和它在同一个目录下的类(即同一个包里的类,这种类不需要 import 导入,就可以直接用),并看不到它的上一层、下一层目录中的类(这种类需要导入,或者使用该类的全限定名来引用)。

但每次使用别的包里的类都写com.xxx.xxx.类名,尤其是对同一个类还进行多次使用时,就很麻烦,所以可以在源代码上方(package语句下)加入 import 语句,把该类导入进来,之后在后面的代码中就可以直接使用该类名,就不用写前面那一段包的信息。(类名

一个 java 程序中,package 语句虽然只能有一个,但 import 语句可以有多个。

  • 如果需要 import 一个包中的很多类,可以使用 * 通配符。
    package com.test;
    
    import com.test.person.*;  // 导入 com.test.person 包下的所有类
    
    import com.test.product.CPU; // 导入 com.test.product 包下的 CPU 类
    
    CPU iPhoneCPU = new CPU();
    

如果 A 源文件中,使用了 package 语句,那么其他源文件要使用 A 中的类时,就要使用 import 语句(通过A中的 package语句中声明的包,定位到想要引用的类)来将需要的类导入。

经过实际试验:只要不加 package 语句,java 就认为这个类是放在 src 下的,不管这个类到底在哪一层文件夹中。而只有同样是在 src 下的类,才能直接引用对方而不需要导入。

访问修饰符

并不是说其他包导入了 A 包中的 a 类,就能像 A 包一样地使用这个 a 类。这里还存在一些 “范围” 问题。

package com.test;

public class Person{
    String name;        // 缺省访问修饰符,就只能被同一个包中的类所访问,即便 Person类被导入到其他包中)
    public String id;
    public int age;
    
}

现在假设 B 包中一个 java 程序(类)导入了这个 com.test.Person,那么它可以使用 public 修饰的属性(如 id、age),但不能使用没有 public 修饰的属性(name)。只有同在 com.test 包中的其他类才能使用 com.test.Person 中没有 public修饰的属性(name)。

[!faq] 如果我引用的是公共类(public class) 也需要 import 吗?
只要是类在不同的包中,就需要 import,不 import 就得用类的全限定名。而关于类的 public 访问修饰符,并不是说是 public 就不用导入,而是当你用全限定名类名或 import 后,这个被导入的类如果是 public 的,才能被访问到。

即可以理解成:我得先找到这个类(import或使用类的全限定名),我再看这个类的访问修饰符来知道这个类能不能被我访问。

不同包中的同名类

src
 |
 |--- A
 |    |
 |    |--- aaa
 |    |--- abc
 |
 |--- B
 |    |
 |    |--- abc
 |
 |--- C
 |    |
 |    |--- abc

假如 A 包中有一个类 abc,那么 A 包中的类 aaa 是可以直接引用这个类 abc 的,此时,如果 aaa 中导入了 B 包中的同名类 abc,则直接在 aaa 中使用 abc是指向 B 包中的 abc(即原来同一个包中的同名类被覆盖),若此时再多导入一个 C 包中的同名类 abc,则会报错,jvm 无法确定 abc 指向哪个包中的 abc 类。

  • java 不像 python 那样可以用import xxx as yyy来给导入的类起一个别名,所以当遇到需要引用多个不同的包中的同名类时,解决方式就是直接使用它们各自的全限定类名。

这里有个要注意的点,如果导入的方式是全限定名导入,那么的确是导入的类会覆盖掉这个包中原先的同名类。但如果导入的方式是用通配符(*),则并不会覆盖掉这个包中的同名类,直接使用该类名,还是会用的是包中原先的同名类。

// com.test 下有一个叫 CPU 的类, com.test.phone 下也有一个叫 CPU 的类
// 当前文件在 com.test 下
package com.test;
import com.test.phone.*;
CPU a = new CPU();	// 此时用的是 com.test 下的 CPU类

package com.test;
import com.test.phone.CPU;
CPU a = new CPU();	// 此时用的是 com.test.phone 下的 CPU类,即覆盖掉 com.test 下的同名类


类的全限定名

简称:类的全名

同一个 java 程序中,全限定名不可重复。

类的全限定名 = 包名 + 类名。

java 中不需要导入(import) 就能直接使用的类:java.lang包中的所有类

java 中,有些自带的函数是可以直接使用的,而不需要显式地使用 import 来导入其所在的类、包。

凡是在 java.lang 包中的类,如 Math 等,都不需要 import 就可以直接使用其中的方法,如:Math.random()

但只要不是 java.lang 包中的,比如 java.util 包中的,就需要显式 import 导入才能使用其中的函数,如:

import java.util.Random;		// 单独导入 java.util 包中的 Random 类

public class TestClass{
	public static void main(String[] args){
		Random abc = new Random();
	}
}

当然,如果是用 IDEA 的话,在你写 Random abc = new Random(); 时,IDEA 会自动帮你在代码上方添加导入语句(import java.util.Random;),而不需要你自己手动添加。如果 IDEA 添加了,你又不小心删除了该导入语句,Random就会标红,此时鼠标停留在其上,按下键盘alt+enter,就会让你选择代码补全,则又能重新自动添加该导入语句。

如果是你直接使用 Math.random(),则你不需要写它的 import 语句,IDEA 也不会帮你添加它的 import 语句,因为就是不需要import 的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值