面向对象2
访问修饰符
private | default | protected | public | |
---|---|---|---|---|
当前类 | ?? | ?? | ?? | ?? |
同一个包 | ?? | ?? | ?? | ?? |
不同包 | ?? | ?? | ?? | ?? |
无关类 | ?? | ?? | ?? | ?? |
参数传递
基本类型和String类型的参数传递(值传递)
? 在进行基本类型的参数传递是,传的是参数的值,并不是参数本身!当main方法调用其他方法时,改变的只是被调用的方法的参数,与main方法内的参数无关。当方法执行结束后,所有的参数对象都会被gc自动销毁回收。
引用类型的参数传递(内存地址传递)
? 引用数据类型非常多,大致包括:
? 类、 接口类型、 数组类型、 枚举类型、 注解类型
? 在进行引用类型的参数传递是,传的是引用类型的参数地址!当main方法调用其他方法时,进行操作的是卖弄传进来的地址,当方法执行结束后,并不影响更改后的参数对象。
public class Test01 {
public static void test(int a, int[] arr){
a = 3;
int[] arr1 ={5,4,3,2,1};
arr[0] = 10;
arr = arr1;
}
public static void main(String[] args) {
int[] arr={1,2,3,4,5};
int a = 0;
test(a,arr);
System.out.println(arr[0]);
}
}
// 输出的结果:
// a = 0;
// arr = {10,2,3,4,5};
final常量
特点
- 被final修饰的类不可以被继承
- 被final修饰的方法被不可以被重写
- 被final修饰的变量不可以更改值
- 被final修饰的引用不可以存储其他对象的内存地址
封装
封装的目的
提供一个统一的用来设置对象属性和访问对象属性的入口
封装的要求
- 所有成员的变量全部私有
- 需要提供公有的set和get方法来提供对象成员变量的访问
- 需要提供一个无参构造方法(必须是public所修饰的)用来给外界创建对象
Java Bean
? 想象一下存在这样一个箱子,其内部被分割成几个格子,每个格子用来存放特定的物品,工人取出或者放入物品后封箱,然后叫了个快递把箱子发出去了。这个箱子就是 Java Bean 啊,取出、放入就是getter、setter,物品就是属性,封箱发出就是序列化和传输。
// 举个栗子
public class Product {
private int id;
private String name;
private double price;
private double stock;
public Product(){}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public double getStock() {
return stock;
}
public void setStock(double stock) {
this.stock = stock;
}
}
继承(Java中只支持单继承)
? Java种的继承解决的是代码复用的问题(父类:共性抽取。子类:功能表现-功能拓展)
? 每一个类都只能有一个父类,但是可以有许多子类
继承带来的好处
- 提高了代码的复用性,提高了软件开发的效率
- 继承的出现让类和类之间产生了关系,提供了多态的前提
// 举个一个栗子
// 新建一个父类Person
public class Person {
public String name;
public int age;
public void eat(){
System.out.println("Person => eat()");
}
}
// 新建一个子类Student继承Person
public class Student extends Person{
public int sno;
public void study(){
System.out.println("Student => study()");
}
}
// 新建一个子类Teacher继承Person
public class Teacher extends Person{
public int tno;
public void teach(){
System.out.println("Teacher => teach()");
}
}
// 主运行类,Student实例化的对象,拥有Person类里的参数和方法
public static void main(String[] args) {
Student student1 = new Student();
student1.name = "student01";
student1.sno = 10001;
student1.eat();
student1.study();
}
继承里的构造方法
当new了子类新对象的时候(即对子类对象进行初始化的时候),父类的构造方法也会执行,且其优先级在子类的构造方法之前,因此父类必须拥有无参构造!
(?)对于子类的构造方法而言,不管是子类的是有参构造方法,还是无参构造方法,都是默认调用父类的无参构造方法,所以不管父类的构造方法是否有做对象的初始化,都必须将父类的无参构造方法给显式的定义出来
super 的三种用法
- 在子类的构造方法种的第一行,用来访问父类的指定构造函数,如果不写,则默认访问父类的无参构造
- 在子类中有和父类名字相同的成员变量时,用于访问父类的指定成员变量(阿里编程规范里不允许使用)
- 在子类有和父类完全相同的方法的时候(方法名相同&参数的数量,顺序,类型相同),访问父类的方法
this 的三种用法
- 在当前子类的构造方法时,会调用自己的其他构造方法
- 访问自己的成员变量
- 访问当前类的其他方法
// 举个一个栗子
// 新建一个父类Person
public class Person {
public String name;
public int age;
// 重写无参构造
public Person(){
System.out.println("Person => Person()");
}
// 重写有参构造
public Person(String name, int age) {
System.out.println("Person => Person(name,age)");
this.name = name;
this.age = age;
}
public void eat(){
System.out.println("Person => eat()")