网站开发从入门到实战wordpress腾讯云插件
- 作者: 五速梦信息网
- 时间: 2026年03月21日 07:37
当前位置: 首页 > news >正文
网站开发从入门到实战,wordpress腾讯云插件,wordpress配图api,子商务网站建设的一般流程前言#xff1a;面向对象程序设计的三大特征就是#xff1a;封装#xff0c;继承#xff0c;多态。在前文介绍了类和对象后#xff0c;我们就可以继而学习什么是封装#xff0c;怎么用类的子类来实现继承和多态 目录
一.面向对象的特性
1.封装性
2.继承性
3.多态性… 前言面向对象程序设计的三大特征就是封装继承多态。在前文介绍了类和对象后我们就可以继而学习什么是封装怎么用类的子类来实现继承和多态 目录
一.面向对象的特性
1.封装性
2.继承性
3.多态性
二.封装
三.继承
1.为什么要有继承
2.继承概念
3.继承的语法
4.父类成员访问
子类中访问父类的成员变量
子类中访问父类的成员方法
5.super 关键字
6.子类构造方法
7.继承方式
四.多态
1.多态的概念
2.多态的实现条件
向上转型
第一种方式直接赋值
第二种方式通过传参
第三种方式通过返回值
重写
3.多态的实现
直接赋值实现多态
通过传参实现多态
4.多态的优缺点
优点
缺点 一.面向对象的特性
面向对象编程是一种先进的编程思想基于对象的编程更符合人的思维模式编写的程序可以更加健壮和强大更容易解决复杂的问题面向对象编程主要体现下面三个特性
1.封装性 面向对象编程的核心思想质疑就是想数据和对数据的操作封装在一起通过抽象从具体的示例中抽取共同的性质形成一般的概念而类的概念也是基于此的具体体现。 比如对于电脑这样一个复杂的设备提供给用户的就只是开关机、通过键盘输入显示器USB插孔等让用户来和计算机进行交互完成日常事务。但实际上电脑真正工作的却是CPU、显卡、内存等一些硬件元件。对于计算机使用者而言不用关心内部核心部件比如主板上线路是如何布局的CPU内部是如何设计的等用户只需要知道怎么开机、怎么通过键盘和鼠标与计算机进行交互即可。因此计算机厂商在出厂时在外部套上壳将内部实现细节隐藏起来仅仅对外提供开关机、鼠标以及键盘插孔等让用户可以与计算机进行交互即可。
2.继承性
继承体现了一种先进的编程模式。子类可以继承父类的属性和功能即继承了父类具有的数据和数据上的操作同时又可以增添子类独有的数据和数据上的操作。就比如人类继承了哺乳类的一般属性和特征但同时又有属于人类自己的属性和特征。
3.多态性
多态有俩种含义一种是操作名称的多态也就是说有多个操作有相同的名字但这些操作所接收的信息类型不同所谓的操作名称的多态是指可以向操作传递不同的信息以便让对象根据相对于收到的消息产生一定的行为。另一种多态是和继承相关的多态是指同一个操作被不同类型对象调用的时候产生的不同的行为例如猫和狗都是哺乳动物都具备哺乳动物“喊叫”的功能但狗和猫对于喊叫这个操作产生的具体行为是不同的狗的喊叫是“汪汪汪”猫的喊叫是“喵喵喵” 二.封装 封装将数据和操作数据的方法进行有机结合隐藏对象的属性和实现细节仅对外公开接口来和对象进行交互 Java中主要通过类和访问权限来实现封装类可以将数据以及封装数据的方法结合在一起更符合人类对事物的认知而访问权限用来控制方法或者字段能否直接在类外使用。Java中提供了四种访问限定符 public 可以理解为一个人的外貌特征谁都可以看见 default 是包访问权限是什么都不写的默认访问权限 protected 一般主要是用在继承当中 private 是只有自己知道其他人都不知道自己的信息。 我们希望类要尽量做到封装隐藏内部实现细节只暴露必要的信息给类的使用者因此我们在使用的时候尽可能的使用必要严格的访问权限如果一个方法能用 private 就尽量不要用 public 一般来说我们将类中的字段设为 private 将方法设为 public 但具体的使用还是得结合实际情况认真选择尽量避免滥用访问权限。 public class Student {private String name;private String gender;private int age;public void printStu() {this.name jake;this.age 12;this.gender man;System.out.println(name:this.name);System.out.println(age:this.age);System.out.println(gender:this.gender);}public static void main(String[] args) {Student s1 new Student();s1.initStu();}
}
就比如我们上面这段代码我们定义的姓名年龄性别都是 private 的但是在类外我们可以通过定义的 public 的方法来访问 private 的字段这样可以使我们的程序更具健全性和安全性 三.继承
1.为什么要有继承
如果我们要用Java来描述猫和狗的话那我们就需要设计俩个类
class Dog {public String name;//名字public int age;//年龄public float weight;//重量// 狗的行为public void eat() {System.out.println(name 正在吃…);}public void sleep() {System.out.println(name 正在睡觉);}public void barks() {System.out.println(name : 旺旺旺~);}
}class Cat {public String name;//名字public int age;//年龄public float weight;//重量// 猫的行为public void eat() {System.out.println(name 正在吃…);}public void sleep() {System.out.println(name 正在睡觉);}void mew(){System.out.println(name 喵喵喵);}
}
但是我们会发现在俩个类中有许多相同的字段和方法如果对于这些重复的部分如果每一次都要重新编写的话是不利于我们编程效率的那我们能不能将这些共性抽取出来呢为了解决此类问题我们就引出了继承的概念 2.继承概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段它允许程序员在保持原有类特性的基础上进行扩展增加新功能这样产生新的类称为 子类或者派生类原有的类我们称为 父类或者基类。继承呈现了面向对象程序设计的层次结构 体现了由简单到复杂的认知过程。继承主要解决的问题是 共性的抽取实现代码复用 例如狗和猫都是动物那么我们就可以将共性的内容进行抽取然后采用继承的思想来达到共用 上述图示中Dog和Cat都继承了Animal类其中Animal类称为父类/基类或超类Dog和Cat可以称为Animal的子类/派生类继承之后子类可以复用父类中成员子类在实现时只需关心自己新增加的成员即可
3.继承的语法
在Java中如果要表示类之间的继承关系需要借助 extends 关键字具体如下 修饰符 class 子类 extends 父类 { // … } 我们可以对于刚才的例子进行继承的操作
class Animal {public String name;//名字public int age;//年龄public float weight;//重量public void eat() {System.out.println(name 正在吃饭);}public void sleep() {System.out.println(name 正在睡觉);}
}
class Dog extends Animal {public void barks() {System.out.println(name : 旺旺旺~~);}
}class Cat extends Animal{void mew() {System.out.println(name 喵喵喵~~~);}
}
我们可以发现代码整体比之前精简了许多但是完成的功能却是一样的
注意
子类会将父类中的成员变量或者成员方法继承到子类中了子类继承父类之后必须要新添加自己特有的成员体现出与基类的不同否则就没有必要继承了
4.父类成员访问
在继承体系中子类将父类中的方法和字段继承下来了那在子类中能否直接访问父类中继承下来的成员呢
子类中访问父类的成员变量
- 子类和父类不存在同名成员变量
public class Base {int a;int b;
}
public class Derived extends Base{int c;public void method(){a 10; // 访问从父类中继承下来的ab 20; // 访问从父类中继承下来的bc 30; // 访问子类自己的c}
}
在这种情况下我们是可以正常访问我们想访问的字段的 2. 子类和父类成员存在变量同名 public class Base {int a;int b;int c;
}
public class Derived extends Base{int a; // 与父类中成员a同名且类型相同char b; // 与父类中成员b同名但类型不同public void method(){a 100; // 访问子类自己新增的ab 101; // 访问子类自己新增的bc 102; // 子类没有c访问的肯定是从父类继承下来的c// d 103; // 编译失败因为父类和子类都没有定义成员变量b}
} 在这种情况下优先访问子类新增的变量或者新赋值的变量如果子类没有再去父类中寻找有就访问父类的变量要是子类父类都没有就编译失败因此我们做出以下总结 在子类方法中 或者 通过子类对象访问成员时 如果访问的成员变量子类中有优先访问自己的成员变量如果访问的成员变量子类中无则访问父类继承下来的如果父类也没有定义则编译报错如果访问的成员变量与父类中成员变量同名则优先访问自己的成员变量访问遵循就近原则自己有优先自己的如果没有则向父类中找 子类中访问父类的成员方法 1. 成员方法名字不同 public class Base {public void methodA(){System.out.println(Base中的methodA());}
}
public class Derived extends Base{public void methodB(){System.out.println(Derived中的methodB()方法);}public void methodC(){methodB(); // 访问子类自己的methodB()methodA(); // 访问父类继承的methodA()// methodD(); // 编译失败在整个继承体系中没有发现方法methodD()}
} 在这种情况下我们完全可以正常访问成员方法没有同名时在子类方法中或者通过子类对象访问方法时则优先访问自己的自己没有时再到父类中找如果父类中也没有则报错 2. 成员方法名字相同 public class Base {public void methodA(){System.out.println(Base中的methodA());}public void methodB(){System.out.println(Base中的methodB());}
}
public class Derived extends Base{public void methodA(int a) {System.out.println(Derived中的method(int)方法);}public void methodB(){System.out.println(Derived中的methodB()方法);}public void methodC(){methodA(); // 没有传参访问父类中的methodA()methodA(20); // 传递int参数访问子类中的methodA(int)methodB(); // 直接访问则永远访问到的都是子类中的methodB()基类的无法访问到}
} 在这种情况下通过子类对象访问父类与子类中不同名方法时优先在子类中找找到则访问否则在父类中找找到则访问否则编译报错。通过派生类对象访问父类与子类同名方法时如果父类和子类同名方法的参数列表不同(重载)根据调用方法适传递的参数选择合适的方法访问如果没有则报错 5.super 关键字 由于设计不好或者因场景需要子类和父类中可能会存在相同名称的成员如果要在子类方法中访问父类同名成员时该如何操作直接访问是无法做到的Java提供了 super 关键字该关键字主要作用在子类方法中访问父类的成员。 public class Base {int a;int b;public void methodA() {System.out.println(Base中的methodA());}public void methodB() {System.out.println(Base中的methodB());}
}
public class Derived extends Base {int a; // 与父类中成员变量同名且类型相同char b; // 与父类中成员变量同名但类型不同// 与父类中methodA()构成重载public void methodA(int a) {System.out.println(Derived中的method()方法);}// 与基类中methodB()构成重写(即原型一致重写后序详细介绍)public void methodB() {System.out.println(Derived中的methodB()方法);}public void methodC() {
// 对于同名的成员变量直接访问时访问的都是子类的a 100; // 等价于 this.a 100;b 101; // 等价于 this.b 101;
// 注意this是当前对象的引用
// 访问父类的成员变量时需要借助super关键字
// super是获取到子类对象中从基类继承下来的部分super.a 200;super.b 201;
// 父类和子类中构成重载的方法直接可以通过参数列表区分清访问父类还是子类方法methodA(); // 没有传参访问父类中的methodA()methodA(20); // 传递int参数访问子类中的methodA(int)
// 如果在子类中要访问重写的基类方法则需要借助super关键字methodB(); // 直接访问则永远访问到的都是子类中的methodA()基类的无法访问到super.methodB(); // 访问基类的methodB()}
}
在子类方法中如果想要明确访问父类中成员时借助 super 关键字即可需要注意的一点是 super 和 this 一样只能在非静态方法中使用
6.子类构造方法
父子父子先有父再有子即子类对象构造时需要先调用父类构造方法然后执行子类的构造方法
public class Base {public Base(){System.out.println(Base());}
}
public class Derived extends Base{public Derived(){super(); // 注意子类构造方法中默认会调用基类的无参构造方法super(),// 用户没有写时,编译器会自动添加而且super()必须是子类构造方法中第一条语句// 并且只能出现一次System.out.println(Derived());}
}
public class Test {public static void main(String[] args) {Derived d new Derived();}
} 输出结果 这里用户没有写 super的话编译器也会自动添加因此输出结果也是一样的 PS在子类构造方法中super(…)调用父类构造时必须是子类构造函数中第一条语句 在子类构造方法中并没有写任何关于基类构造的代码但是在构造子类对象时先执行基类的构造方法然后执行子类的构造方法因为子类对象中成员是有两部分组成的基类继承下来的以及子类新增加的部分 。父子父子肯定是先有父再有子所以在构造子类对象时候 先要调用基类的构造方法将从基类继承下来的成员构造完整然后再调用子类自己的构造方法将子类自己新增加的成员初始化完整
7.继承方式
在实际生活中继承的概念不只是单一的一对一的继承往往是有多种继承方式的诸如下图的动物类继承 在Java中我们也支持多种继承方式但是值得注意的是与 C 不同的是Java不允许多继承的方式存在也就是说在Java中一个类不允许同时继承多个类即便是允许多层继承我们一般也不建议进行超过3层的继承就像递归一样多层的嵌套往往是不利于我们编程效率的在遇见这种情况的时候我们一般就得思考别的办法对代码进行重构 四.多态
1.多态的概念
我们一般常说的多态大多是在继承的基础上而讲的当一个操作被不同类型对象调用后产生的不同的行为我们就将其叫做多态比如下面的打印机这个例子对于打印这个操作我们用不同的对象彩色打印机黑白打印机调用的时候产生的结果就不一样彩色打印机打印出来的是彩色的黑白打印机打印出来的是黑白的而这种不同的结果就是多态的体现 又比如吃食物这个概念在猫和狗的身上上就会有不一样的体现猫吃猫粮狗吃狗粮总的来说对于同一件事发生在不同对象身上就会有不同的结果 2.多态的实现条件
在Java中要实现多态必须满足以下几个条件
必须在继承体系之下子类必须要对父类中的方法进行重写通过父类的引用调用重写的方法
而我们要理解多态就要理解下面俩个点
理解向上转型理解重写
向上转型
向上转型可以分为3种方式
第一种方式直接赋值
我们这里以Animal类举例并且有一个Cat类来继承他
class Animal {String name;int age;//构造方法public Animal(String name,int age) {this.name name;this.age age;}public void eat() {System.out.println(this.name 正在吃食物~
);} } class Cat extends Animal {//构造方法public Cat(String name,int age) {super(name,age);} } 在这种情况下我们用父类对象直接引用子类对象就叫做向上转型 public static void main(String[] args) {Cat cat new Cat(布偶,3);Animal animal1 cat;animal1.eat();Animal animal2 new Cat(橘猫,2);animal2.eat();} 我们可以看见输出结果俩个对象都访问的是父类中的eat方法都是吃食物 第二种方式通过传参 我们在原有的代码上再加入一个Dog类 class Animal {String name;int age;//构造方法public Animal(String name,int age) {this.name name;this.age age;}public void eat() {System.out.println(this.name 正在吃食物);} } class Dog extends Animal {//构造方法public Dog(String name,int age) {super(name,age);} } class Cat extends Animal {//构造方法public Cat(String name,int age) {super(name,age);} } 我们新建一个方法传入一个动物类型然后调用eat方法我们需要的参数是父类Animal但是我们传入的子类对象Cat或者Dog中的对象也可以完成我们的传参这种我们也称之为向上转型 public static void fun(Animal animal) {animal.eat();}public static void main(String[] args) {Cat cat new Cat(布偶,3);Dog dog new Dog(哈士奇,2);fun(cat);fun(dog);} 我们可以看见输出结果俩个对象都访问的是父类中的eat方法都是吃食物 第三种方式通过返回值 我们再这里新建俩个方法 public static Animal fun1(Animal animal) {return new Cat(布偶,3);}public static Animal fun2(Animal animal) {return new Dog(哈士奇,2);} 我们的返回值是父类Animal但是我们返回的却是Animal的子类Cat或者Dog这也算是向上转型 重写 当我们的子类继承了父类后我们对父类中的方法不改变其方法名参数列表返回值我们只改变方法内部的细节通过这种操作后我们得到的方法就叫做重写的方法而这样的操作就叫做重写 这里有些需要注意的地方 子类在重写父类的方法时一般必须与父类方法原型一致 返回值类型 方法名 (参数列表) 要完全一致被重写的方法返回值类型可以不同但是必须是具有父子关系的访问权限不能比父类中被重写的方法的访问权限更低。例如如果父类方法被public修饰则子类中重写该方法就不能声明为 protected父类被static、private修饰的方法、构造方法都不能被重写重写的方法, 可以使用 Override 注解来显式指定. 有了这个注解能帮我们进行一些合法性校验. 例如不小心将方法名字拼写错了 (比如写成 aet), 那么此时编译器就会发现父类中没有 aet 方法, 就会编译报错, 提示无法构成重写 我们就拿刚才的动物类进行举例我们对继承的eat方法进行重写 class Animal {String name;int age;//构造方法public Animal(String name,int age) {this.name name;this.age age;}public void eat() {System.out.println(this.name 正在吃食物~~);} } class Dog extends Animal {//构造方法public Dog(String name,int age) {super(name,age);}public void eat(){System.out.println(this.name 正在吃狗粮~);} } class Cat extends Animal {//构造方法public Cat(String name,int age) {super(name,age);}public void eat(){System.out.println(this.name 正在吃猫粮~);} } 3.多态的实现 在简单理解了向上转型和重写后我们就可以充分理解多态了将不同的向上转型的方式和重写进行结合我们就可以实现多态了 直接赋值实现多态 public static void main(String[] args) {Animal animal1 new Dog(哈士奇,2);animal1.eat();Animal animal2 new Cat(橘猫,2);animal2.eat();} 我们观察输出结果我们会发现与刚才的结果是完全不同的我们这一次不再是访问量父类对象中的eat方法我们访问的子类中的方法eat 我们对于同样的eat方法用在不同的对象上的结果是完全不一样的用在Dog对象上就是吃狗粮用在Cat对象上就是吃猫粮而这就是我们多态的体现 通过传参实现多态 public static void fun(Animal animal) {animal.eat();}public static void main(String[] args) {Animal animal1 new Dog(哈士奇,2);Animal animal2 new Cat(橘猫,2);fun(animal1);fun(animal2);} 我们观察输出结果同样可以实现多态 4.多态的优缺点 优点 能够降低代码的 圈复杂度, 避免使用大量的 if - else可扩展能力更强 什么叫 圈复杂度 ? 圈复杂度是一种描述一段代码复杂程度的方式. 一段代码如果平铺直叙, 那么就比较简单容易理解. 而如果有很多的条件分支或者循环语句, 就认为理解起来更复杂.因此我们可以简单粗暴的计算一段代码中条件语句和循环语句出现的个数, 这个个数就称为 圈复杂度.如果一个方法的圈复杂度太高, 就需要考虑重构. 假如我们有个画图形的要求 class Shape {//属性….public void draw() {System.out.println(画图形);} } class Rect extends Shape{Overridepublic void draw() {System.out.println(♦);} } class Cycle extends Shape{Overridepublic void draw() {System.out.println(●);} } class Flower extends Shape{Overridepublic void draw() {System.out.println(❀);} } 如果是按照一般方式我们要连续按照顺序打印多个图像我们可能会如下设计整体略显臃肿 public static void drawShapes() {Rect rect new Rect();Cycle cycle new Cycle();Flower flower new Flower();String[] shapes {cycle, rect, cycle, rect, flower};for (String shape : shapes) {if (shape.equals(cycle)) {cycle.draw();} else if (shape.equals(rect)) {rect.draw();} else if (shape.equals(flower)) {flower.draw();}}} 但如果是使用多态的话我们就可以提高很高的效率也方便我们阅读 public static void drawShapes() {// 我们创建一个 Shape 对象的数组.Shape[] shapes {new Cycle(), new Rect(), new Cycle(),new Rect(), new Flower()};for (Shape shape : shapes) {shape.draw();}} 缺点 代码的运行效率降低当父类和子类都有同名属性的时候通过父类引用只能引用父类自己的成员属性构造方法没有多态性 在我们实现多态的过程中如果我们只实现向上转型而不实现重写的话那我们就只能调用父类中的方法无法实现多态相对的如果只实现重写不实现向上转型的话虽然可以调用子类的方法但是不能实现多态的概念 因此我们总结如下如果我们要实现多态就需要在继承体系之下并且子类必须要对父类中的方法进行重写然后通过父类的引用调用重写的方法 本次的分享就到此为止了希望我的分享能给您带来帮助也欢迎大家三连支持你们的点赞就是博主更新最大的动力如有不同意见欢迎评论区积极讨论交流让我们一起学习进步有相关问题也可以私信博主评论区和私信都会认真查看的我们下次再见
- 上一篇: 网站开发从零到凡科快图网站
- 下一篇: 网站开发搭建seo优化报告
