面向对象
面向对象和面向过程
面向对象编程( Object Oriented Programming)过程编程是关于编写对数据执行操作的过程或方法,而面向对象的编程是关于创建包含数据和方法的对象。面向对象的三大特性为:封装性(Encapsulation)、继承性(Inherit)、多态性(Polymorphism)。
关于面向对象与面向过程的知识不再做仔细介绍,具体可以看这篇文章:
面向对象与面向过程语言的区别_bieleyang的博客-CSDN博客_面向对象和面向过程的区别
封装性(Encapsulation)
封装(Encapsulation)是面向对象三大特征之一,对于程序合理的封装让外部调用更加方便,更加利于写作。同时,对于实现者来说也更加容易修正和改版代码。
1.封装的优点
- 提高代码的安全性
- 提高代码的复用性
- 便于修改内部代码,提高代码可维护性。
- 便于调用者使用,便于扩展和协作
2.封装的解释
class Student {
String name;//声明姓名属性
int age;//声明年龄属性
void read() {
System.out.println("大家好,我是"+name+",年龄是"+age);
}
}
public class OOP4{
public static void main(String[] args) {
Student stu=new Student();//创建学生对象
stu.name="理博";//为name赋值
stu.age=-20;//为age赋值
stu.read();//调用对象的方法
}
}
在此代码中为学生对象的age赋值为-20,在程序中不会出现编译错误,但在现实生活中,-20显然是一个不合理的年龄。为避免这种情况的出现,在设计Student类时,会对成员变量做一些访问的限制,不允许外界随意访问,这就需要通过封装来实现。
3.封装的实现
class Student {
private String name;//声明姓名属性
private int age;//声明年龄属性
public int setAge;
public void getName() {
return name;
}
public void setName(String name) {
this.name=name;
}
public int getAge() {
return age;
}
public void setAge() {
if(age<=0) {
System.out.println("输入的年龄有误");
}
else {
this.age=age;
}
}
public void read() {
System.out.println("大家好,我是"+name+",年龄是"+age);
}
}
public class OOP4{
public static void main(String[] args) {
Student stu=new Student();//创建学生对象
stu.setName("理博");//为name赋值
stu.setAge=(-20);//为age赋值
stu.read();//调用对象的方法
}
}
在此代码中,使用private关键字将name和age属性变为私有变量,并对外界提供公有的访问方法。当调用setAge()方法传入age时,会对age进行判断,符合条件才会进行传入。
4.权限修饰符
修饰符 | 同一个类 | 同一个包中 | 子类 | 所有包的所有类 |
private | * | |||
默认 | * | * | ||
protected | * | * | * | |
public | * | * | * | * |
继承性(Inherit)
1.继承的概念
在JAVA中,类的继承是指在一个现有类的基础上去构建一个新的类,构建出来的新的类称为子类,现有的类称为父类。在程序中,如果想声明一个类继承一个类,就需要用到extends关键字。
2.继承的实现
class Animal {
private String color;
private int age;
public Animal() {
}
public Animal(String color, int age) {
this.color=color;
this.age=age;
}
public void eat() {
System.out.println(".....eating.....");
}
public void sleep() {
System.out.println(".....sleeping.....");
}
public void introduce() {
System.out.println("color"+color+",age"+age);
}
}
class Dog extends Animal {
private String nickName;
public Dog(){
}
public Dog(String color,int age,String nickName){
super(color,age);
this.nickName=nickName;
}
public void guard(){
System.out.println(".....Dog guarding.....");
}
}
public class Test {
public static void main(String[] args) {
Dog dog = new Dog("黑色",3,"小黄");
dog.eat();
dog.sleep();
dog.introduce();
dog.guard();
}
}
3.继承注意事项
- 类只支持单继承,不允许多重继承
- 多个类可以继承一个父类
- 一个类的父类可以继承另外的父类
- 子类和父类是相对而言的
4.方法的重写
class Animal {
void shout(){
System.out.println("动物发出叫声");
}
}
class Dog extends Animal{
void shout() {
System.out.println("汪汪汪...");//重写父类中的Animal方法
}
}
public class oop3{
public static void main(String[] args) {
Dog dog=new Dog();
dog.shout();//调用dog重写的shout()方法
}
}
在此代码中,Dog类继承了Animal类,并对父类的shout()方法进行重写。
在子类重写父类方法时,不能使用比父类中被重写方法更加严格的访问权限,如果权限缩小,在编译中会报错。
多态性(Polymorphism)
1.多态的概念
多态是指,在同一行为中,通过不同的子类,可以体现出来的不同的形态。JAVA中多态主要有方法的重载和方法的重写(对象的多态性)两种形式。
2.多态的引入
abstract class Animal{
abstract void shout();//定义抽象类Animal
}
class Cat extends Animal{//定义Cat类继承Animal抽象类
public void shout(){//实现shout方法
System.out.println("喵喵......");
}
}
class Dog extends Animal{//定义Dog类继承Animal抽象类
public void shout(){//实现shout方法
System.out.println("汪汪......");
}
}
public class Test{
public static void main(String args[]){
Cat an1=new Cat();
Dog an2=new Dog();
an1 shout();//创建Cat对象,使用Animal类型的变量an1引用
an2 shout();//创建Dog对象,使用Animal类型的变量an2引用
}
}
在此代码中,Cat和Dog类继承了Animal抽象类,并重写了Animal类中的shout()方法。在Test类中,Cat和Dog类对象向上转型成了Animal类型的对象,然后通过Animal类型的对象an1和an2调用了shout()方法,这种由于参数不同而导致执行结果不同的现象就称为多态。
3.多态注意事项
-
多态是方法的多态,与属性无关
-
多态的存在要有3个必要条件:继承、方法重写、父类引用指向子类对象
-
父类引用指向子类对象后,用该父类引用调用子类重写的方法,此时就出现了多态
4.对象类型的转换
- 向上转型
将子类对象赋给父类引用,称为向上转型,自动进行类型转换。向上转型可以调用的子类继承的方法,但不能调用子类特有的方法。需要特别理解的是如果子类重写了父类的方法,向上转型后通过父类引用调用的却是真实子类重写的方法。
//父类类型 变量名 = new 子类类型();
Person p = new Student();
- 向下转型
将父类的引用变量转换为子类类型,称为向下转型。向下转型后就可以调用子类特有的方法了。
//子类类型 变量名 = (子类类型) 父类类型的变量;
Student stu = (Student) p;//变量p 实际上指向Student对象