茫茫人海千千万万,感谢这一秒你看到这里。希望我的文章能对你的有所帮助!共勉! 愿你在未来的日子,保持热爱,奔赴山海!
Java基础知识(封装和继承)
一
封装
那封装是什么呢?
在面向对象程式设计方法中,封装(英语: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;}}
编写测试User的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: 太子爷哪吒-----------password: 520
二
继承
继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。描述的是事物之间的所属关系,这种关系是:is-a
的关系。
提高代码的复用性(减少代码冗余,相同代码重复利用)。 使类与类之间产生了关系。 子类拥有父类非 private 的属性、方法。 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。 子类可以用自己的方式实现父类的方法。 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。 Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 B 类继承 A 类,C 类继承 B 类,所以按照关系就是 B 类是 C 类的父类,A 类是 B 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。
extends关键字可以申明一个类是从另外一个类继承而来的,一般形式如下:
class 父类 {}class 子类 extends 父类 {}
class A {}class B extends A { (对的)}class C extends A, B { (错的)}class C extends B { (对的)}

编写一个父类极其对应的子类信息 结构如下: 
代码如下: 父类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;}}
package com.nz.pojo;/*** 继承了Person特有的name, age,* 没有额外的独有属性和方法*/public class Student extends Person{}
package com.nz.pojo;/*** 继承了Person特有的name, age,* 多了自己独有的工资属性还有独有的教书方法*/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());}}
结果如下:
太子爷哪吒181999.99老师在认真教书!哪吒12
并不是父类的所有内容都可以给子类继承的。
2.6.1 super 与 this 关键字
这里先将这两个关键字,super和this在继承关系中,运用比较频繁。
super关键字:我们可以通过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() 都必须是在构造方法的第一行,所以不能同时出现。
2.6.2 构造器不能被继承
子类不能继承父类的构造器(构造方法或者构造函数),它只是调用(隐式或显式)。因为子类有自己的构造器。值得注意的是子类可以继承父类的私有成员(成员变量,方法),只是子类无法直接访问而已,可以通过
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子类继承Personclass 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子类继承Personclass 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):张三三
2.6.3 final修饰的类不能被继承
修饰类:表示该类不能被继承; 修饰方法:表示方法不能被重写; 修饰变量:表示变量只能一次赋值以后值不能被修改(常量)。
对于一个 final 变量,如果是基本数据类型的变量,则其数值一旦在初始 化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不 能再让其指向另一个对象。 当用 final 修饰一个类时,表明这个类不能被继承。final 类中的所有成员 方法都会被隐式地指定为 final 方法。 使用 final 方法的原因有两个。第一个原因是把方法锁定,以防任何继承 类修改它的含义;第二个原因是效率。在早期的 Java 实现版本中,会将 final 方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用 带来的任何性能提升(现在的 Java 版本已经不需要使用 final方法进行这些优化了)。类中所有的 private 方法都隐式地指定为 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//}
2.7.1 介绍
2.7.2 使用场景与案例
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("我们一起学猫叫,一起喵喵喵!让我们一起撒个娇");}}
动物都可以跑!
我们一起学猫叫,一起喵喵喵!让我们一起撒个娇
2.7.2 @Override重写注解
@Override:注解,重写注解校验! 这个注解标记的方法,就说明这个方法必须是重写父类的方法,否则编译阶段报错。 建议重写都加上这个注解,一方面可以提高代码的可读性,一方面可以防止重写出错! 加上后的子类代码形式如下: class Cat extends Animal {
声明不变,重新实现
方法名称与父类全部一样,只是方法体中的功能重写了!
@Override
public void sing(){
System.out.println("我们一起学猫叫,一起喵喵喵!让我们一起撒个娇");
}
}
2.7.3 注意事项
方法重写是发生在子父类之间的关系。 子类方法覆盖父类方法,必须要保证权限大于等于父类权限。 子类方法覆盖父类方法,返回值类型、函数名和参数列表都要一模一样。



生活明朗,万物可爱
保持热爱,奔赴山海

文章转载自太子爷哪吒,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。





