封装
- 该露的露,该藏的藏
- 封装(数据的隐藏)
- 属性私有,get/set
public class Student {
//属性私有
private String name;//名字
private int id;//学号
private char sex;//性别
//方法
//提供一些可以操作这个 属性的方法!
//提供一些public的 get , set方法
//get获得这个数据
public String getName(){
return this.name;
}
//set给这个数据设置值
public void setName(String name){
this.name = name;
}
//alt+inset快速get,set
}
意义:
- 提高程序安全性,保护数据
- 隐藏代码实现细节
- 统一接口
- 系统可维护性
方法名相同,参数列表相同就是同一个方法
继承
继承关系的两个类: (子类继承父类使用关键字extends来表示)
- 子类(派生类)
- 父类(基类)
JAVA中类只有单继承,没有多继承!
- 子类可以继承父类的所有方法
- 父类如果用private私有,子类就不可以继承
- Ctrl+h打开树结构
- 在JAVA中,所有的类都默认继承Object
例子:
//人:父类
public class Person {
public void say(){
System.out.println("ha");
}
private int money= 10_0000_0000;
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
}
//学生:子类,派生类
public class Student extends Person{
}
//调用子类
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.say();
student.getMoney();
System.out.println(student.getMoney());
}
}
super,this和参数的逻辑关系示例
//人:父类
public class Person {
protected String name = "hu";
}
//学生:子类,派生类
public class Student extends Person{
private String name = "xiao";
public void test(String name){
System.out.println(name);//胡
System.out.println(this.name);//这个name是子类里的“xiao”
System.out.println(super.name );//这个name 是父类里的"hu"
}
}
//调用
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.test("胡");
}
}
子类有隐藏代码:调用父类的无参构造
调用父类的构造器,必须要在子类构造器的第一行
super注意点
- super调用父类的构造方法,必须要在构造方法的第一个
- super必须只能出现在子类的方法或者构造方法中
- super和this 不能同事调用构造方法
不同点 | super | this |
---|---|---|
代表的对象不同 | 代表父类对象的应用 | 本身调用这个对象 |
前提 | 只能在继承条件才可以使用 | 没有继承也可以使用 |
构造方法 | 父类的构造 | 本类的构造 |
重写方法
子类重写了 父类的方法
静态方法
//父类
public class A {
public static void test(){
System.out.println("A=>test()");
}
}
//子类
public class B extends A{
public static void test(){
System.out.println("B=>test()");
}
}
//静态方法调用
public class Application {
public static void main(String[] args) {
//方法的调用只和左边定义的数据类型有关
B a = new B();
a.test();//B=>test()
//父类的引用指向了子类
A b = new B();
b.test();//A=>test()
//内存分析:static是和类一起加载的,并且引用变量都能够调用,这也是为啥用A定义了B就直接调用了A的static方法。
//具体在下面多态中会有详细解释
}
}
重写只能在非静态方法下
非静态方法
//父类
public class A {
public void test(){
System.out.println("A=>test()");
}
}
//子类
public class B extends A{
//重写
//快捷键:Alt+Insert:override
@Override//注解,有功能的注释!
public void test() {
System.out.println("B=>test()");
}
}
//非静态方法调用
public class Application {
public static void main(String[] args) {
B a = new B();
a.test();//B=>test()
A b = new B();//子类重写了父类的方法
b.test();//B=>test()
/**
*即b是B new出来的对象,因此调用了B的方法
*因为静态方法是类的方法,而非静态是对象的方法
*有static时,b调用了A类的方法,因为b是用A类定义的
*没有static时,b调用的是对象的方法,而b是用B类new的
*/
}
}
小结
重写:需要有继承关系,子类重写父类的方法。
- 方法名必须相同
- 参数列表必须相同
- 修饰符:范围可以扩大 public>protected>Default(什么都不写)>private
- 抛出的异常:范围,可以被缩小,但不能扩大。
重写,子类的方法和父类必须要一致,方法体不同。
重写的原因:
- 父类的功能,子类不一定需要,或者不一定满足
多态
//父类
public class Persion {
public void run(){
System.out.println("run");
}
}
//子类
public class Student extends Persion{
@Override
public void run() {
System.out.println("son");
}
public void eat(){
System.out.println("eat");
}
}
//调用
public class Application {
public static void main(String[] args) {
//可以指向的引用类型就不确定了:父类的引用指向子类
//Student 能调用的方法就是自己的或者继承父类的
Student s1 = new Student();
//Persion 父类型,可以指向子类,但是不能调用子类独有的方法
Persion s2 = new Student();
//对象能执行哪些方法,主要看对象左边的类型,和右边关系不大
s1.run();
s1.eat();
s2.run();
}
}
多态注意事项
- 多态是方法的多态,属性没有多态
- 父类和子类,有联系
- 存在条件:继承关系,方法需要重写,父类引用指向子类对象
不能重写的有
- static 方法,属于类,它不属于实例
- final 常量
- private 方法,私有的