0 前言
面向对象编程是一种编程范式,它把现实世界中的事物抽象为对象,对象具有属性和方法,属性表示对象的特征,方法表示对象的行为。对象之间可以通过消息进行交互。面向对象编程的优点是可以提高代码的复用性、可维护性和可扩展性。在本文中,我们将介绍面向对象编程的三个高级特性:封装、继承和多态。我们将学习如何利用封装来隐藏对象的内部实现细节,如何利用继承来建立类之间的层次关系和代码重用,如何利用多态来实现不同对象对同一消息的不同响应。我们还将探讨一些面向对象编程的应用场景和设计原则。
1 构造方法
1.1 定义
是一个方法名和类名相同且不用定义返回值类型的方法。
1.2 语法
系统默认提供无参构造方法,不执行任何操作并隐藏。
1.3 作用
对象初始化(创建对象时对对象的属性进行赋值操作)
1.4 重载
1)方法名相同
2)参数类型或是个数不同
3)和返回值、修饰符无关
普通方法重载:
public class User{
//普通方法重载
//条件:一定是多个方法之间才能构成重载
//1.方法名相同,参数类型不同
public void show1(int a){}
public void show1(String a){}
//2.方法名相同,参数个数不同
public void show2(int a){}
public void show2(int a,int b){}
//1.和返回值无关-->不构成方法重载
public void show3(){}
public int show3(){}
//2.和修饰符无关-->不构成方法重载
public void show4(){}
private void show4(){}
}
构造方法重载:
public class Person{
//构造方法重载
//1.方法名相同,参数类型不同
public Person(int a){}
public Person(String a){}
//2.方法名相同,参数个数不同
public Person(int a){}
public Person(int a,int b){}
//3.和修饰符无关-->不构成构造方法的重载
public Person(){}
pricate Person(){}
}
2 static
2.1 static修饰方法和变量
public class Dog{
//static修饰的变量,可以通过类直接调用
static String name;
//static修饰的方法,可以通过类直接调用
public static void eat(){
System.out.println("吃鱼")
}
public static void main(String[] args){
//非static修饰的变量和方法,需要通过创建对象的方式调用
//Dog dog = new Dog();
//dog.name = "旺财";
//dog.eat();
Dog.name = "旺财";
System.out.println(Dog.name);
Dog.eat();
}
}
2.2 static如何分配内存空间
public class Mouse{
static int age;
public static void main(String[] args){
Mouse mouse1 = new Mouse();
mouse1.age = 18;
Mouse mouse2 = new Mouse();
mouse2.age = 22;
System.out.println(mouse1.age);
System.out.println(mouse2.age);
//结果都是22
}
}
2.3 static/非static的区别
3 封装
3.1 为什么使用封装
代码没有问题,业务存在问题,例如属性值赋值随意导致业务不合理,所以需要封装。
3.2 什么是封装
将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问。
3.3 封装的步骤
①如何隐藏 private
②如何方法 setter/getter
③如何控制语句 if判断
3.4 this关键字
4 继承
4.1 为什么使用继承
多类之间拥有多个相同的属性或是方法,解决方法是将相同的属性和方法抽取出来,封装到一个新的类中,并继承新的类。
4.2 继承语法
A extends B
1.如果A extends B --> A是B的子类,B是A的父类
2.java中一个类只能继承一个父类
3.继承的关键字是extends
4.3 继承实战
public class Dog extends Pet{
}
public class Pet{
String name;
int health;
int height;
}
public class Test{
public static void main(String[] args){
Dog dog = new Dog();
dog.name = "旺财";
System.out.println(dog.name);
}
}
4.4 super
定义:调用父类的成员
规范:
super只能出现在子类的方法和构造方法中
super调用构造方法时,只能是第一句
super不能访问父类的private成员
1)调用父类构造器
public class Pet{
public Pet(){}
public Pet(int a){}
}
public class Dog extends Pet{
public Dog(){
//调用父类无参构造器
super();
}
public Dog(int a){
//调用父类有参构造器
super(a);
}
}
2)调用父类属性
public class Pet{
String name;
}
public class Dog extends Pet{
//调用父类的name属性
String name = super.name;
}
3)调用父类方法
public class Pet{
public void show(){}
}
public class Dog extends Pet{
public void print(){
//调用父类的普通方法
super.show();
}
}
4.5 访问修饰符
访问修饰符 | 本类 | 同包 | 子类 | 其他 |
---|---|---|---|---|
private | √ | |||
默认(friendly) | √ | √ | ||
protected | √ | √ | √ | |
public | √ | √ | √ | √ |
4.6 继承初始化顺序
父类属性初始化>>父类构造器初始化>>子类属性初始化>>子类构造器初始化
5 重写
5.1 重写
public class Father{
public void show(){
System.out.println("父亲的show方法");
}
}
public class Son extends Father{
//子类重写父类的方法
public void show(){
System.out.println("儿子的show方法");
}
}
public class Test{
public static void main(String[] args){
Son son = new Son();
son.show();
}
}
5.2 重写的规范
1)方法名相同
2)参数列表相同
3)返回值类型相同或者是其子类
4)访问权限不能严于父类
5)构造方法不能被重写
方法重载和方法重写的区别:
0 | 位置 | 方法名 | 参数表 | 返回值 | 访问修饰符 |
---|---|---|---|---|---|
方法重写 | 子类 | 相同 | 相同 | 相同或是其子类 | 不能比父类更严格 |
方法重载 | 同类 | 相同 | 不同 | 无关 | 无关 |
6 抽象
6.1 抽象类
1)抽象类的关键字是abstract
2)抽象类的特点是不能实例化
3)抽象方法的特点是没有方法体
4)抽象类中可以有非抽象方法
public abstract class Pet{
String name;
String pwd;
public abstract void eat();
}
public class Dog extends Pet{
public void eat(){
System.out.println("吃狗粮");
}
}
public class Penguin extends Pet{
public void eat(){
System.out.println("吃鱼儿");
}
}
public class Test{
public static void main(String[] args){
Dog dog = new Dog();
dog.eat();
Penguin penguin = new Penguin();
penguin.eat();
}
}
6.2 抽象方法
1)抽象方法没有方法体
2)抽象方法必须在抽象类中
3)抽象方法必须在子类中被实现,除非子类是抽象类
6.3 final
1.final修饰类
特点:不能被继承
2.final修饰方法
特点:不能被重写
3.final修饰属性
特点:不能被二次赋值
7 多态
7.1 定义
生活中的定义:同一种操作,由于条件不同,产生的结果也不同
计算机中的定义:父类引用指向子类对象
7.2 多态三要素
1)编写具有继承关系的父类和子类
2)子类重写父类方法
3)使用父类的引用指向子类的对象
7.3 多态表现方式
1)将父类作为方法形参
public void feed(Pet pet){
System.out.print("主人喂食");
pet.eat();
}
2)将父类作为方法的返回值
public Pet getPet(int typeId){
Pet pet = null;
if(typeId == 1){
pet = new Dog();
}else if(typeId == 2){
pet = new Penguin();
}
return pet;
}
7.4 向上转型和向下转型
向上转型
定义:子类转换成父类(自动转换)
public Pet getPet(int typeId){
Pet pet = null;
if(typeId == 1){
pet = new Dog(); //向上转型
}else if(typeId == 2){
pet = new Penguin(); //向上转型
}
return pet;
}
向下转型
定义:父类转换成子类(强制转换)
public void play(Pet pet){
if(pet instanceof Dog){ //instance判断pet类型是否属于Dog类型
Dog dog = (Dog)pet; //向下转型
dog.catchFlyDisc();
}elseif(pet instanceof Penguin){
Penguin penguin = (Penguin)pet; //向下转型
penguin.swimming();
}
}
8 接口
为什么使用接口:
接口可以实现Java中的"多"继承
接口的特性和语法:
1)接口的关键字是interface
2)接口中的所有方法都是用public abstract
修饰的
3)接口不能实例化
4)实现类必须实现接口的所有方法
5)实现类可以实现多个接口
6)接口中所有变量都是静态常量
创建接口的步骤:
①创建接口
②创建实现类
③调用接口
public interface USB{
public abstract void charge();
}
public class Phone implements USB{
@Override
public void charge(){
System.out.println("充电。。。")
}
}
public class Test{
public static void main(String[] args){
USB usb = new Phone();
usb.charge;
}
}