java_Learning1
【JAVA学习笔记1】 面向对象基础
JAVA知识点多,写点笔记,整理3.25 周一上午JAVA课内容,
方法
private字段
当字段被修饰为private
时,外部代码无法访问该字段。我们可以用调用类里的方法间接访问该字段,确保了封装性和安全性
private方法
和private
字段一样,private
方法也不允许类外的代码调用。
1 | public class Main { |
观察上述代码,
calcAge()
是一个private
方法,外部代码无法调用,但是,内部方法getAge()
可以调用它。此外,我们还注意到,这个Person
类只定义了birth
字段,没有定义age
字段,获取age
时,通过方法getAge()
返回的是一个实时计算的值,并非存储在某个字段的值。这说明方法可以封装一个类的对外接口,调用方不需要知道也不关心Person
实例在内部到底有没有age
字段。
可变参数(E)
可变参数用类型…定义,可变参数相当于数组类型:
1 | class Animal{ |
上面的
setNames()
就定义了一个可变参数。调用时,可以这么写:1 | Animal g = new Animal(); |
完全可以把可变参数改写为
String[]
类型:1 | class Animal { |
但是,调用方需要自己先构造String[]
,比较麻烦。例如:
1 | Animal g = new Animal(); |
另一个问题是,调用方可以传入null
:
1 | Animal g = new Animal(); |
而可变参数可以保证无法传入null,因为传入0个参数时,接收到的实际值是一个空数组而不是null。
可变参数感觉跟重载异曲同工嘛,都由参数形式决定方法的结果。
参数绑定(E)
调用方把参数传递给实例方法时,调用时传递的值会按参数位置一一绑定。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 //基本类型参数绑定
public class Main {
public static void main(String[] args) {
Person p = new Person();
int n = 15; // n的值为15
p.setAge(n); // 传入n的值
System.out.println(p.getAge()); // 15
n = 20; // n的值改为20
System.out.println(p.getAge()); // 15还是20?
}
}
class Person {
private int age;
public int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
}此时
n
和p.age
两者互不影响,setAge()
方法复制了n
的值
重点:
1 | //引用类型参数绑定 |
fullname
和name
同步更改,原因是new String[]{}
创建了一个对象,而fullname
和p.name
指向了同一个对象。关键是创建了一个对象构造方法
构造方法初始化实例,构造方法名就是类名,无返回值。
调用该方法,必须用new
操作符
如果既对字段进行初始化,又在构造方法中对字段进行初始化,会发生什么?
在Java中,创建对象实例的时候,按照如下顺序进行初始化:
先初始化字段:int age = 10;表示字段初始化为10,double salary;表示字段默认初始化为0,String name;表示引用类型字段默认初始化为null;
执行构造方法的代码进行初始化。
因此,构造方法的代码是后运行,将覆盖一开始字段初始化。
多构造方法,用法类似方法重载。
1 | class Person { |
方法重载(OverLoad
):
同一个类里定义几个方法名相同,功能相似但参数不同(参数个数、参数类型不同)的方法
换而言之,以参数内容决定方法内容,省去多个函数名
1 | class Hello { |
其他知识点
this
的用法、对象运算符、匿名对象(类)、包和修饰符
this 用法
- 调用类内的成员变量
1
2
3
4
5
6public class MyClass {
private int num;
public void setNum(int num) {
this.num = num;
}
} 调用本类中的其他方法
1
2
3
4
5
6
7public class MyClass {
private int num;
public void print(MyClass mc) {
System.out.println(mc.num);
}
}调用本类中的其他构造方法
1
2
3
4
5
6
7
8
9
10
11public class MyClass {
private int num;
public MyClass() {
this(0);
}
public MyClass(int num) {
this.num = num;
}
}
对象运算符(instanceof)
该运算符用于操作对象实例,检查该对象是否是一个特定类型(类类型或接口类型)。
instanceof
运算符使用格式如下:
( Object reference variable ) instanceof (class/interface type)
如果运算符左侧变量所指的对象,是操作符右侧类或接口(class/interface)的一个对象,那么结果为真。
1 | String name = "James"; |
如果被比较的对象兼容于右侧类型,该运算符仍然返回 true。
1 |
|
以上实例编译运行结果为:true
匿名对象
普通的类对象在使用时会定义一个类类型的变量,用来保存new出来的类所在的地址。而匿名类取消掉了这个变量,这个地址由编译器来处理,并且在new出来之后,它占用的内存会有JVM自动回收掉。后续无法再使用了。
1 | public class Student{ |
匿名对象最常用的方式是作为函数的参数,上述的打印语句 “豆zza来喽ヘ(~ω~ヘ)” 是一个匿名对象,由于字符串是以对象的形式存储的,所以这里实际上就是一个没有使用对象引用的匿名对象。
匿名类
如果一个内部类在整个操作中只使用一次,就可以定义为匿名内部类。匿名内部类也就是没有名字的内部类,这是java为了方便我们编写程序而设计的一个机制.只创建一个它的对象,以后再不会用到这个类,使用匿名内部类就比较合适。
匿名内部类伴随着接口一起使用:
1 | public interface USB{ |
在Demo这个类的main方法中创建了一个局部的内部类,这个内部类没有名字,也就是创建了一个匿名内部类。
匿名对象(类)中文本均来自 *Java 学习笔记(8)——匿名对象与内部类
包(package)
- 将功能相近的类放在同一个包里
- 某些访问是以包为单位
- 由于不同包里可能有相同的类名,一定程度上可以避免命名冲突
- package语句必须是文件中第一条语句
- WARNING :包没有父子关系。java.util和java.util.zip是不同的包,两者没有任何继承关系。
private、public、protected、无修饰
访问级别 | 访问控制修饰符 | 同类 | 同包 | 子类 | 不同包 |
---|---|---|---|---|---|
公开 | public | ✔ | ✔ | ✔ | ✔ |
受保护 | protected | ✔ | ✔ | ✔ | × |
默认 | 无修饰符 | ✔ | ✔ | × | × |
私有 | private | ✔ | × | × | × |
主要参考:
- java上课内容
- 廖雪峰java课堂
- Java 学习笔记(8)——匿名对象与内部类