Java中的封装、继承和多态是Java面向对象编程中的三大核心概念,了解它们的作用和用法对于Java程序员来说至关重要。
封装
封装是将对象的状态和行为进行封装,预防外部直接访问和修改对象属性的一种机制。Java中通过访问权限控制来实现封装,一般分为public、private、protected和default四种访问权限。
示例1:
public class Person {
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
if (age < 0) {
this.age = 0;
}
else {
this.age = age;
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
以上代码展示了一个Person类,类中有两个私有属性:age和name,对外只提供了公共的getter和setter方法,以便外部使用。其中setter方法对传入的参数进行了合法性校验,如果传入的年龄小于0默认设置为0。
示例2:
public interface UserDao {
void save(User user);
void delete(int id);
User find(int id);
}
public class UserDaoImpl implements UserDao {
@Override
public void save(User user) {
// 保存用户
}
@Override
public void delete(int id) {
// 删除用户
}
@Override
public User find(int id) {
// 查询用户
return null;
}
}
以上代码展示了一个Dao层的接口和其实现类,通过接口和实现类的方式,将实现类中的方法声明和具体实现分离,在上层业务逻辑的调用时只需调用接口中的方法即可,实现类内部具体实现可以随时更换而不影响上层业务逻辑。这个也就是面向接口编程的思想。
继承
继承是Java面向对象编程中的另一个重要概念,它允许子类继承父类中的属性和方法,使得代码实现更加简单、便捷。同时,子类还可以重写父类中的方法,以满足子类的特殊需求。Java中一个类只能继承一个父类,但是可以通过多重继承和接口来实现类的复用。
示例1:
public class Animal {
public void eat() {
System.out.println("Animal is eating");
}
}
public class Dog extends Animal {
@Override
public void eat() {
System.out.println("Dog is eating");
}
}
以上代码展示了一个Animal类和其子类Dog,子类继承了父类中的eat()方法,并对其进行了重写。在使用子类Dog的eat()方法时,会优先执行子类中的方法。
示例2:
public interface UserDao {
void save(User user);
void delete(int id);
User find(int id);
}
public interface UserService {
void save(User user);
void delete(int id);
User find(int id);
}
以上代码展示了一个用户相关的Dao层接口和Service层接口,可以发现两者中定义的方法是几乎一致的。为了避免代码的重复,可以将两者的共同方法抽象成一个父接口BaseService,再分别让UserDao和UserService去继承它:
public interface BaseService<T> {
void save(T t);
void delete(int id);
T find(int id);
}
public interface UserDao extends BaseService<User> {
}
public interface UserService extends BaseService<User> {
}
这样,BaseService就拥有了save、delete和find三个方法,UserDao和UserService就不用再重写这些代码了。
多态
多态是Java面向对象编程中的第三大核心概念,它允许不同的子类对象对同一消息作出响应。通过多态,程序可以根据具体的运行时情况动态地选择执行哪个方法,使得程序更加灵活和可扩展。多态可以通过方法覆盖和方法重载来实现。
示例1:
public class Shape {
public void draw() {
System.out.println("Shape is drawing");
}
}
public class Circle extends Shape {
@Override
public void draw() {
System.out.println("Circle is drawing");
}
}
public class Rect extends Shape {
@Override
public void draw() {
System.out.println("Rect is drawing");
}
}
public class Test {
public static void main(String[] args) {
Shape s1 = new Circle();
Shape s2 = new Rect();
s1.draw(); // Circle is drawing
s2.draw(); // Rect is drawing
}
}
以上代码展示了一个Shape类和其两个子类Circle和Rect,还有一个Test类,使用父类Shape的引用分别指向了Circle类和Rect类的实例,在这个过程中调用draw()方法时会根据实际的对象类型分别执行Circle和Rect中的draw()方法。
示例2:
public class Calculator {
public int add(int a, int b) {
return a + b;
}
public int add(int a, int b, int c) {
return a + b + c;
}
public double add(double a, double b) {
return a + b;
}
}
public class Test {
public static void main(String[] args) {
Calculator calculator = new Calculator();
int result1 = calculator.add(1, 2);
int result2 = calculator.add(1, 2, 3);
double result3 = calculator.add(1.0, 2.0);
System.out.println(result1); // 3
System.out.println(result2); // 6
System.out.println(result3); // 3.0
}
}
以上代码展示了一个Calculator类,其中重载了add()方法,它可以接收2个int型参数、3个int型参数和2个double型参数,并返回对应的结果。在Test类中,我们分别调用了3个不同版本的add方法,并输出了结果。这个就是方法的重载,编译器会根据调用时传入的参数类型和数量来自动匹配正确的方法。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java中的封装、继承和多态,你真的都懂了吗 - Python技术站