java学习第七天
面向对象的三大特征(封装、继承、多态)
封装
使用private修饰符对属性进行修饰,限制属性的访问权限,只有类内部能够访问这样的属性,其他的类通过对象,属性的方式是无法访问的,从而对对象的状态(数据)进行保护,外部类要访问的话需要通过get、set的方法,保证属性统一访问。
- 学生类:
有一些属性,都是用private修饰
提供一些get、set方法访问这些属性。在调用set的时候可以限制赋值的内容,在调用get时可以返回指定的数据,转换和限制的逻辑封装在类的方法中。
public class Student {
private String name;
private int sex;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
String result = sex == 1 ? "男" : "女";
return result;
}
public void setSex(int sex) {
//限制性别的赋值,不允许随便赋值。
if (sex < 0 || sex > 1) {
//抛出异常
throw new RuntimeException("性别只能为0或1");
}
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
-
使用学生类
-
使用学生类不能直接反问属性,必须通过get、set方法。
如果给属性赋值,不符合要求(比如性别就不能设置0和1以外的值),就会报异常。
用get方法,读取属性,会读取到学生类中转换之后的内容(不如这里的男、女)
package com.HQYJ.PrivateStud;
public class StudentTest {
public static void main(String[] args) {
Student student = new Student();
//私有成员变量,不能直接用对象,属性方式访问
//student.name = "小李";
student.setName("张三");
student.setSex(1);
student.setAge(22);
System.out.println(student.getSex());
}
}
访问修饰符
控制访问权限的关键字称为访问修饰符,有private、default、protected、public。
访问修饰符可以用在类,成员变量以及方法前面,局部变量不需要访问修饰符
同类(当前类) | 同一个包 | 子类 | 其他类 | |
---|---|---|---|---|
private:私有的 | √ | x | x | x |
default默认的(不写修饰符) | √ | √ | x | x |
protected:受保护的 | √ | √ | √ | x |
public公共的 | √ | √ | √ | √ |
继承
A类可以通过extends关键字继承B类,继承之后a类可以有一些B类中的属性或方法。实现代码中的重复利用。
语法:
[修饰符] class 子类 extends 父类{
}
子类也叫派生类、衍生类、subClass。
父类也可以叫基类,超类、superClass。
继承的特点
- 继承只能是单继承(只能有一个父类)
- 继承可以多重继承,如:A继承自B,B又继承自C。
- Object是所有类的父类(所有的类都是继承自Object)。
- 子类可以重写(覆盖)父类的方法。
- 创建子类的时候会先执行父类的构造方法。
代码案列
父类Grop定义了一个成员变量,一个方法area()
子类Rectangle继承了父类Grop,Rectangle自动有name属性和area()方法
子类中定义自己的属性,也可以写自己的方法,还可以重写父类继承来的方法。
-
父类Grop
public class Grap { protected String name; public void area(){ System.out.println("面积"); } }
-
子类
public class Rectangle extends Grap{ private double length;//矩形的宽度 private double width;//矩形的高度 public Rectangle(float length, float width) { this();//调用无参构造方法,在构造方法中,调用其他的构造方法,要写在第一行。 this.length = length; this.width = width; } public Rectangle() { this.name = "矩形"; } @Override public void area() { System.out.println(length * width); } }
-
测试代码
public static void main(String[] args) { //返回length 5 , width 3.6的参数。 Rectangle rectangle = new Rectangle(5,3.6); rectangle.area(); System.out.println(rectangle.name); }
重写和重载
重写override(覆盖)
子类继承父类的时候,子类对父类的方法代码重新写过就叫重写。
重写的特征
- 方法名、参数的列表(个数、类型、顺序)、返回值必须要一致
- 访问权限(修饰符)不能比父类的更小(可以与父类的访问权限一样,也可以更大)
- 如果要抛出异常,不能比父类的异常更大
重载overload
在一个类中(不一定要继承),如果有多个方法的方法名相同,参数的列表不同(个数、类型、顺序),这些同名的方法就称为重载。
重载的特性:
- 方法名相同
- 参数的列表不同(个数、类型、顺序)
- 返回类型和修饰符没有要求。
public class Rect {
/**
* 计算正方形的面积
*/
public void area(int width) {
System.out.println(width * width);
}
/**
* 计算长方形的面积
*/
public void area(int width,int length) {
System.out.println(width * length);
}
}
this和super关键字
这两个关键字都可以指代对象或构造方法
当成对象用
public Grap() {
//this用在构造方法里,代表当前对象
this.name = "形状";
System.out.println(this.name);
}
public void setAge(int age){
//this用在set方法里,代表当前对象
//为了区分成员变量和局部变量,因为两个都叫age
this.age = age;
}
public void parenArea(){
//在子类中访问父类的方法,就要用到super.方法
super.area();
}
当成构造方法使用
- 在构造方法中调用构造方法,用this替代方法名。
- 在构造方法中调用构造方法,调用语句只能放在第一行
- 子类要调用父类的构造方法,用super()
- 如果子类的构造方法没有调用父类的构造方法,默认会调用父类的无参构造方法
- 如果父类没有无参的构造方法,在子类的构造方法中必须要调用父类的有参的构造方法
Parent.java
public class Parent {
private int age;
private String name;
private int sex;
public Parent() {
System.out.println("无参构造器");
}
public Parent(String name, int sex) {
this();
this.name = name;
this.sex = sex;
System.out.println("两个参数");
}
public Parent(int age, String name, int sex) {
//构造方法调构造方法时放在第一行。
this(name,sex);
this.age = age;
System.out.println("三个参数");
}
public static void main(String[] args) {
Parent parent = new Parent(22,"zhangsan",1);
}
}
Son.java
public class Son extends Parent {
private int age;
private String name;
private int sex;
public Son(String name, int sex) {
super(name,sex);
this.name = name;
this.sex = sex;
System.out.println("两参");
}
public Son(int age, String name, int sex) {
super(age,name,sex);
this.age = age;
this.name = name;
this.sex = sex;
System.out.println("三参");
}
public Son() {
super();//执行父类的构造方法,(不写也会自动调用)
System.out.println("无参");
}
public static void main(String[] args) {
Son son = new Son();
new Son(22,"李四",0);
}
}
相关面试题
-
构造方法被调用的时候一定会调用对象?
错误,子类的构造方法执行的时候,要先调用父类的构造方法,这时候父类其实并没有创建出对象。
-
构造方法能重载吗?能重写吗?
可以重载,例如有参构造器和无参构造器。
不可以重写。