随着系统越来越复杂,类会越来越多,那么类之间的访问边界必须把握好,面向对象的开发原则要遵循“
高内聚、低耦合
”,而“高内聚,低耦合”的体现之一:
高内聚
:类的内部数据操作细节自己完成,不允许外部干涉;低耦合
:仅暴露少量的方法给外部使用,尽量方便外部调用封装可以认为是一个保护屏障,防止该类的代码和数据被其他类随意访问,加强了代码的
安全性
。隐藏对象内部的复杂性,只对外公开简单和可控的访问方式,从而提高系统的可扩展性、可维护性。
public
、protected
、缺省
、private
。具体访问范围如下:修饰符 | 本类内部 | 本包内 | 其他包的子类 | 其他包非子类 |
---|---|---|---|---|
private | √ | × | × | × |
缺省 | √ | √ | × | × |
protected | √ | √ | √ | × |
public | √ | √ | √ | √ |
成员变量/属性私有化
私有化类的成员变量,提供公共的get和set方法,对外暴露获取和修改属性的功能。
实现步骤:
private 数据类型 变量名 ;
例:
第一步:使用private修饰成员变量
public class Person {
private String name;
private int age;
private boolean marry;
}
第二步:提供 get\set 方法,可以访问成员变量:
public class Person {
private String name;
private int age;
private boolean marry;
public void setName(String n) {
name = n;
}
public String getName() {
return name;
}
public void setAge(int a) {
age = a;
}
public int getAge() {
return age;
}
public void setMarry(boolean m){
marry = m;
}
public boolean isMarry(){
return marry;
}
}
第三步:测试
public class PersonTest {
public static void main(String[] args) {
Person p = new Person();
//实例变量私有化,跨类是无法直接使用的
p.setName("张三");
System.out.println("p.name = " + p.getName());
p.setAge(23);
System.out.println("p.age = " + p.getAge());
p.setMarry(true);
System.out.println("p.marry = " + p.isMarry());
}
}
注意:
开发中,一般成员实例变量都习惯使用private修饰,再提供相应的public权限的get/set方法访问。
对于final的实例变量,不提供set()方法。
对于static final的成员变量,习惯上使用public修饰。
注意:使用this访问属性和方法时,如果在本类中未找到,会从父类中查找。
重载:在同一个类中,方法名相同,参数列表不同
特点:与修饰符、返回值类型无关,只看参数列表,且参数列表必须不同(参数的个数或类型)。调用时,根据方法参数列表的不同来区别。
例:
//返回两个整数的和
public int add(int x,int y){
return x+y;
}
//返回三个整数的和
public int add(int x,int y,int z){
return x+y+z;
}
//返回两个小数的和
public double add(double x,double y){
return x+y;
}
使用static修饰的成员变量就是静态变量(或类变量、类属性)
1.适用范围
在Java类中,可用static修饰属性、方法、代码块、内部类
2.被修饰后成员的特点
语法格式:
[修饰符] class 类{
[其他修饰符] static 数据类型 变量名;
}
3.静态变量的特点:
1.语法格式
用static修饰的成员方法就是静态方法。
[修饰符] class 类{
[其他修饰符] static 返回值类型 方法名(形参列表){
方法体
}
}
2.静态方法的特点
例:
为描述和处理个人信息,定义类Person:
class Person{
public String name;
public int age;
public Date birthDate;
}
为描述和处理学生信息,定义类Student:
class Student{
public String name;
public int age;
public Date birthDate;
public String school;
}
通过继承,可以简化Student类的定义:
class Student extends Person{
public String school;
}
说明:Student类继承了父类Person的所有属性和方法,并增加了一个属性school。Person中的属性和方法,Student都可以使用。
is-a
的关系,提供了多态的前提。
is-a
的关系。可见,父类更通用或更一般,子类更具体。通过 extends关键字,可以声明一个类B继承另外一个类A,定义格式如下:
[修饰符] class 类A {
...
}
[修饰符] class 类B extends 类A {
...
}
继承中的基本概念:
类A,称为父类、超类、基类(base class)、SuperClass
类B,称为子类、派生类(derived class)、SubClass
代码举例:
父类:
public class Animal {
// 定义name属性
String name;
// 定义age属性
int age;
// 定义动物的吃东西方法
public void eat() {
System.out.println(age + "岁的"
+ name + "在吃东西");
}
}
子类:
public class Cat extends Animal {
int count;//记录每只猫抓的老鼠数量
// 定义一个猫抓老鼠的方法catchMouse
public void catchMouse() {
count++;
System.out.println("抓老鼠,已经抓了"
+ count + "只老鼠");
}
}
测试类:
public class TestCat {
public static void main(String[] args) {
// 创建一个猫类对象
Cat cat = new Cat();
// 为该猫类对象的name属性进行赋值
cat.name = "Tom";
// 为该猫类对象的age属性进行赋值
cat.age = 2;
// 调用该猫继承来的eat()方法
cat.eat();
// 调用该猫的catchMouse()方法
cat.catchMouse();
cat.catchMouse();
cat.catchMouse();
}
}
1.子类会继承父类所有的实例变量和实例方法
2.子类不能直接访问父类中私有的(private)的成员变量和方法
3.在Java 中,子类不是父类的子集,而是对父类的扩展
4.Java中一个类只能有一个父类,不可以有多个直接父类。
5.Java支持多层继承
class A{}
class B extends A{}
class C extends B{}
6、一个父类可以同时拥有多个子类
class A{}
class B extends A{}
class D extends A{}
class E extends A{}
1.super的理解
在Java类中使用super来调用父类中的指定操作:
注意:
如果子类没有重写父类的方法,只要权限修饰符允许,在子类中可以直接调用父类的方法;
如果子类重写了父类的方法,在子类中需要通过super才能调用父类被重写的方法,否则默认调用的子类重写的方法
例:
public class SmartPhone extends Phone{
//重写父类的来电显示功能的方法
public void showNum(){
//来电显示姓名和图片功能
System.out.println("显示来电姓名");
System.out.println("显示头像");
//保留父类来电显示号码的功能
super.showNum();//此处必须加super.,否则就是无限递归,那么就会栈内存溢出
}
}
方法前面没有super.和this.
方法前面有this.
方法前面有super.
2.子类中调用父类中同名的成员变量
3.总结
变量前面有this
变量前面super
this
super
1.重写的概念
重写只发生在继承关系中,方法名、参数列表、返回类型相同,但方法实现的过程不同就称为方法重写。
例:
//假设有一个Animal类,其中有一个makeSound方法。
class Animal {
public void makeSound() {
System.out.println("Animal makes a sound");
}
}
//然后有一个Dog子类,它重写了makeSound方法。
class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Dog barks");
}
}
2.方法重写的要求