Python 官方文档:入门教程 => 点击学习
目录一. 封装1.1 封装的目的1.2 封装的好处1.3 封装的步骤1.4 封装的例子1.5 小结二. 继承2.1 继承的介绍2.2 生活中的继承2.3 继承的好处2.4 继承的格式
那封装是什么呢?
在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。
修改属性的可见性来限制对属性的访问(一般限制为private),例如:
public class Person {
private String name ; // 姓名
private String gender ; // 性别
private int age; // 年龄
}
这段代码中,将 name 、sex和 age 属性设置为私有的,只能本类才能访问,其他类都访问不了,如此就对信息进行了隐藏。
对每个值属性提供对外的公共方法访问,也就是创建一对赋取值方法,用于对私有属性的访问,例如:
public class Person {
private String name ; // 姓名
private String gender ; // 性别
private int age; // 年龄
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setGender(String gender) {
this.gender = gender;
}
public String gender(){
return gender;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
}
采用 this 关键字调用本类中的属性,也就是类中的成员变量。主要为了解决实例变量(private String name)和局部变量(setName(String name)
中的name变量)之间发生的同名的冲突。
创建一个用户类User:
package com.nz.pojo;
public class User {
private String username; // 用户名
private String passWord; // 密码
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
demo:EncapsulationDemo
代码如下:
package com.nz;
import com.nz.pojo.User;
public class EncapsulationDemo {
public static void main(String[] args) {
User user = new User();
user.setUsername("太子爷哪吒");
user.setPassword("520");
System.out.println("username: " + user.getUsername() + "-----------"
+ "password: " + user.getPassword());
}
}
执行结果如下:
username:太子爷哪吒-----------password520
封装实际上是将类的某些信息隐藏在类的内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的访问和操作。就是把我们想提供给外界的一些方法给暴露出来,以便外界能调用到我们。
继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。描述的是事物之间的所属关系,这种关系是:is-a 的关系。
继承:就是子类继承父类的属性和行为,使得子类对象(实例)可以直接具有与父类相同的属性、相同的行为。子类可以直接访问父类中的非私有的属性和行为。
兔子和长颈鹿属于食草动物类,老虎和狮子属于食肉动物类。而食草动物和食肉动物又是属于动物类。
那是不是兔子、长颈鹿、老虎、狮子都属于动物类呢?答案是没错滴!虽然食草动物和食肉动物都是属于动物,但是两者的属性和行为上有差别,所以子类会具有父类的一般特性也会具有自身的特性。我们就可以再多个类中存在相同属性和行为时,我们可以将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那一个类即可。
在Java当中会通过extends
关键字可以申明一个类是从另外一个类继承而来的,一般形式如下:
class 父类 {
}
class 子类 extends 父类 {
}
需要注意一点: Java 不支持多继承,但支持多重继承。就如下:
class A {
}
class B extends A { (对的)
}
class C extends A, B { (错的)
}
class C extends B { (对的)
}
顶层父类是Object类。所有的类默认继承Object,作为父类。
结构如下:
代码如下:
父类Person:
package com.nz.pojo;
public class Person {
private String name ;
private int age ;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
子类Student没有额外的属性和方法:
package com.nz.pojo;
public class Student extends Person{
}
子类Teacher多了一个工资的属性和独有的教书方法:
package com.nz.pojo;
public class Teacher extends Person{
// 工资
private double salary ;
// 特有方法
public void teach(){
System.out.println("老师在认真教书!");
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
编写测试代码:
package com.nz;
import com.nz.pojo.Student;
import com.nz.pojo.Teacher;
public class InheritDemo {
public static void main(String[] args) {
Teacher teacher = new Teacher();
teacher.setName("太子爷哪吒");
teacher.setAge(18);
teacher.setSalary(1999.99);
System.out.println(teacher.getName());
System.out.println(teacher.getAge());
System.out.println(teacher.getSalary());
teacher.teach();
Student student = new Student();
student.setName("哪吒");
student.setAge(12);
//student.setSalary(1999.99); // student没有工资属性,报错!
System.out.println(student.getName());
System.out.println(student.getAge());
}
}
结果如下:
太子爷哪吒
18
1999.99
老师在认真教书!
哪吒
12
从结果来看,子类继承父类,就可以直接得到父类的成员变量和方法。而子类可以编写一些特有的属性和方法,但是是否可以继承所有成分呢?
并不是父类的所有内容都可以给子类继承的:
这里先将这两个关键字,super和this在继承关系中,运用比较频繁。
super和this完整的用法如下:
this.成员变量 -- 本类的
super.成员变量 -- 父类的
this.成员方法名() -- 本类的
super.成员方法名() -- 父类的
具体演示,创建测试InheritDemo2:
package com.nz;
public class InheritDemo2 {
public static void main(String[] args) {
Animal a = new Animal();
a.eat();
Cat cat = new Cat();
cat.eatFish();
}
}
class Animal {
void eat() {
System.out.println("animal : eat");
}
}
class Cat extends Animal {
void eat() {
System.out.println("cat : eat");
}
void eatFish() {
this.eat(); // this 调用自己的方法
super.eat(); // super 调用父类方法
}
}
调用结果如下:
animal : eat
cat : eat
animal : eat
注意:
子类的每个构造方法中均有默认的super(),调用父类的空参构造。手动调用父类构造会覆盖默认的super()。
super() 和 this() 都必须是在构造方法的第一行,所以不能同时出现。
getter/setter
方法访问父类的private成员变量。super
关键字调用父类的构造器并配以适当的参数列表。super
关键字调用父类构造器,系统会自动调用父类的无参构造器。演示过程:
package com.nz;
public class InheritDemo3 {
public static void main(String[] args) {
System.out.println("------Teacher 类继承------");
Teacher teacher = new Teacher();
Teacher teacher2 = new Teacher("张三");
System.out.println("------Student 类继承------");
Student student = new Student();
Student student2 = new Student("张三三");
}
}
// 父类
class Person {
private String name;
Person(){
System.out.println("调用了父类的无参构造器: Person()");
}
Person(String name) {
System.out.println("调用了父类的带参构造器: Person(String name)");
this.name = name;
}
}
// Teacher子类继承Person
class Teacher extends Person{
private String name;
Teacher(){
// 自动调用父类的无参数构造器 因为会有默认super();
System.out.println("Teacher");
}
public Teacher(String name){
super("太子爷哪吒"); // 调用父类中带有参数的构造器
System.out.println("Teacher(String name):"+name);
this.name = name;
}
}
// Student子类继承Person
class Student extends Person{
private String name;
Student(){
super("heihei"); // 调用父类中带有参数的构造器
System.out.println("SubClass2");
}
public Student(String name){ // 自动调用父类的无参数构造器
System.out.println("Student(String name):"+name);
this.name = name;
}
}
结果如下:
------Teacher 类继承------
调用了父类的无参构造器: Person()
Teacher
调用了父类的带参构造器: Person(String name)
Teacher(String name):张三
------Student 类继承------
调用了父类的带参构造器: Person(String name)
SubClass2
调用了父类的无参构造器: Person()
Student(String name):张三三
final 关键字主要用在三个地方:变量、方法、类。
final 的特点:
我们测试下修饰类后到底能不能继承:
package com.nz;
public class InheritDemo4 {
}
// 父类
final class Fu {
private String name;
}
//class Zi extends Fu{ // Cannot inherit from final 'com.nz.Fu' 会显示没办法继承Fu
//}
结果:可以看出来在被final修饰的Fu类没办法继承,而且在编译期间就会报错了,没办法通过运行。
子类中出现与父类一模一样的方法时(返回值类型,方法名和参数列表都相同),会出现覆盖效果,也称为重写或者复写。声明不变,重新实现。
发生在子父类之间的关系。
子类继承了父类的方法,但是子类觉得父类的这方法不足以满足自己的需求,子类重新写了一个与父类同名的方法,以便覆盖父类的该方法。
写个测试案例:
package com.nz;
public class InheritDemo5 {
public static void main(String[] args) {
// 创建子类对象
Cat lanMao = new Cat();
// 调用父类继承而来的方法
lanMao.run();
// 调用子类重写的方法
lanMao.sing();
}
}
class Animal{
public void sing(){
System.out.println("动物都可以唱歌!");
}
public void run(){
System.out.println("动物都可以跑!");
}
}
class Cat extends Animal {
public void sing(){
System.out.println("我们一起学猫叫,一起喵喵喵!让我们一起撒个娇");
}
}
运行结果:
动物都可以跑!
我们一起学猫叫,一起喵喵喵!让我们一起撒个娇
可以看出,蓝猫调用了重写后的sing方法。
加上后的子类代码形式如下:
class Cat extends Animal {
// 声明不变,重新实现
// 方法名称与父类全部一样,只是方法体中的功能重写了!
@Override
public void sing(){
System.out.println("我们一起学猫叫,一起喵喵喵!让我们一起撒个娇");
}
}
这篇文章就到这里了,如果这篇文章对你也有所帮助,希望您能多多关注编程网的更多内容!
--结束END--
本文标题: Java基础-封装和继承
本文链接: https://lsjlt.com/news/129635.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-03-01
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0