——目录——
◉ 类与对象的概念
=> 类 :是一组相似事物的描述
- 属于引用数据类型
- 所以它和其他类型一样,是抽象的、不占用内存的。
=> 对象 :是类的具体表现
- 属于数据,
- 所以它占据内存(且存放在堆内存中)
有static修饰的属于类,没有的属于对象
◉ 修饰符概念
private (私有的):只能在本类中访问
缺省 (友好的):能在同一个包下访问
protected (受保护的):能在同一个包下和子类访问
public (公开的):能在任何地方访问到
◉ 类(class、变量、构造器)
—— class
① 一个文件可以有多个 class ,但编译过后还是会生成多个.class文件
② 有且仅有 1 个被 public 修饰的 class,且名字应和文件名完全一致
③ 每个 class 都可以有一个 main 函数入口,在运行时可以选择使用哪一个入口(但不推荐)
④ 五大成分:成员变量,构造器,方法,内部类,代码块
⑤ 修饰符:缺省 | public ,abstract | final 可组合使用
—— 变量
详见:【Java之轨迹】第二章:局部变量、实例变量和类变量总结
—— 构造器
可使用的修饰符:public,private,protected,缺省
默认会有无参的构造器,但如果自己定义了构造器,该无参构造器会被覆盖
◉ 方法
① 分类
有 static 修饰的方法属于类,可以由类调用(类名.方法),也可以由对象调用。一般由类来调用。
没有 static 修饰的方法属于对象,只能由对象调用
② 方法重载
条件:在同一个类中,方法名相同,形参列表不同
(修饰符和返回值类型不起决定性作用)
③ 参数个数可变的方法
定义方法:(参数类型…参数名称)
注意点1: 可变参数可以看成一个数组
public static void test(int...num)
{
for(int n: num) System.out.print(n + " ");
}
public static void main(String[] args)
{
test(new int[]{2, 3, 4});
test(5, 6, 7, 8);
}
运行结果:2 3 4 5 6 7 8
注意点2: 所以:可变参数和数组不能构成重载!
注意点3: 可变参数只能放在参数列表的最后一个(也说明了可变参数只能有一个)
◉ 封装
作用:使内部变量变得可控、安全
为了达到封装的目的
通常将成员变量设置为 private , 将方法设置为public
转而通过 set() get() 设置和访问成员变量的值
① 包
建包:在类的最上面加 package 包名
导包:在类的最上面加 import 包名.类名 / 包名.*
② this 关键字
this 代表的是对象(当前正在调用该方法的对象)
this(参数) 代表调用构造器
可以用在方法体(只能为实例方法)和构造器中
this代表的是当前正在调用该方法的对象,所以只能用于实例方法中而不能用于静态方法
举例:
public class Test1
{
private int num;
// 用在构造器中
public Test1(int num)
{
this.num = num;
}
// 用在实例方法中
public void setNum(int num)
{
if(num > 0)
this.num = num;
else
/* 提示错误... */
}
public int getNum()
{
return this.num;
}
}
setNum() 中体现了封装使变量可控安全,可以通过内部处理筛选合理的赋值。
注意:this 一定一定不能出现在静态方法中,因为静态方法可以由类直接调用,这时候 this 指的是哪个对象就完全不知道了
this 在方法中也可以省略,默认会帮忙加上
但,前提是该方法体内没有同名的变量!!!
如上面的setNum() 中,方法体内已经由名字为num的变量,这时候当然不能写num=num;而应该使用 this 表明左值为该对象的成员变量
[ 就近原则,变量同名则优先选择距离近的而屏蔽远的 ]
◉ 继承
在类名之后使用 extends 进行继承
作用:提高代码复用
① 单继承
Java 只支持单继承,一个类只能有一个直接父类,可以有多个间接父类
如果没用extends继承,默认继承 Object (都是对象)
② 方法重写
发生在子父类之间
子类重写一个方法替代父类的方法
方法名和形参列表完全一致
子类的返回值类型需要和父类相同或者更小
子类的访问权限需要和父类相同或者更大
③ 重写自检查机制
推荐加 @Override ,为重写自检查
说明此方法必须是重写的方法(父类有此方法)
否则会报错(防止名字写错没有成功重写)
④ 不可重写的情况
被 private 修饰的方法不能被重写,在子类中写完全一样的被认为是不同的方法而不是重写,如果加上@Override 就会报错 “方法不会实现或覆盖超类的方法”
public class Main extends Test2
{
//@Override
private int getInt()
{
return 10;
}
public static void main(String[] args)
{
Main main = new Main();
System.out.println(main.getInt() );
}
}
public class Test2
{
private int getInt()
{
return 100;
}
}
运行结果:10
看似好像 getInt 方法被重写了,但如果把注释去掉,加上了@Override
就可以看到提示:
说明检查结果是重写并没有成功。
静态方法也不能被重写,出现的情况和private的一样
⑤ 构造器调用
子类构造器总会在第一行调用父类构造器一次
如果没有显式地调用,就会默认地调用一次
注意:默认调用的只是无参构造器,如果自己写的父类中有有参构造器却没有自己写无参构造器,那么就不能依靠子类构造器去默认调用,会出错,必须自己显式调用然后传入参数。所以父类一般应手动加上一个无参构造器
public class Main extends Test2
{
public Main()
{
System.out.println("子类Main无参构造器");
}
public static void main(String[] args)
{
Main main = new Main();
}
}
public class Test2
{
public Test2()
{
System.out.println("父类Test2无参构造器");
}
}
运行结果:
但如果此时将父类 Test2 改为:
public class Test2
{
/* [注释1]
public Test2()
{
System.out.println("父类Test2无参构造器");
}
*/
public Test2(int i)
{
System.out.println("父类Test2有参构造器");
}
}
那么会出现:
此时有两种方法:
第一种是显式地调用 super 如:
第二种是在父类手动添加无参构造器,如:将 [注释1] 去掉
⑥ this 和 super
this关键字
可以调用当前对象的构造器和方法以及变量
super关键字
可以调用当前对象的父类的构造器和方法及变量
如果方法已经被子类重写了,但子类依旧想调用父类的同名方法,可以使用super
this 和 super 后面直接加括号代表调用构造器
这时候只能放在方法的第一行而不能是其他位置
且这种方法只能在构造器体中调用而不能在其他方法体中
因此它们不能同时出现
利用上面 ⑤ 的例子,将 Main 的构造器改为:
那么将出现错误:
但如果是默认调用无参构造器 super() ,那么 superI() 和 this(1) 就可以同时起作用,如完整代码:
public class Main extends Test2
{
public Main()
{
this(1);
System.out.println("子类Main无参构造器");
}
public Main(int i)
{
System.out.println("子类Main有参构造器");
}
public static void main(String[] args)
{
Main main = new Main();
}
}
public class Test2
{
public Test2()
{
System.out.println("父类Test2无参构造器");
}
public Test2(int i)
{
System.out.println("父类Test2有参构造器");
}
}
运行结果:
矢志不移,星辰为我而转(寒冰小澈)