Java 封装
什么是封装?
封装:
装:把属性装载
封:私有化,提供访问权限
在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。
封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。
要访问该类的代码和数据,必须通过严格的接口控制。
封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。
适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。
封装的优点:
- 良好的封装能够减少耦合。
- 类内部的结构可以自由修改。
- 可以对成员变量进行更精确的控制。
- 隐藏信息,实现细节。
怎么进行封装?
第一步:属性私有化(使用private关键字进行修饰属性)
第二步:对外提供简单的操作入口
第二步详解:
1个属性对外提供一个set方法和一个get方法。外部程序只能通过set方法修改属性,只能通过get方法读取属性。(可以在set方法设立关卡来保证数据的安全性)
注意:set和get方法都是实例方法,不能带static。
不带static的方法称为实例方法(就是之前的非静态方法),实例方法的调用必须先new对象(用引用.方法名的方式)
set和get方法的书写规范:
set:
public void set +属性 名首字母大写(1个参数){
xxx=1个参数;
}
get:
public 返回值类型 get+属性名首字母大写(无参){
return xxx;
}
代码示例:
public class Person {
//非私有化属性
String address;
//私有化属性
private int age;
private String name;
//提供对外访问的方法setter和getter
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;//(在这里表示本类的引用,
// 用来区分成员变量和局部变量同名的冲突问题)
// this关键字在下篇文章单独讲解
}
public String getName() {
return name;
}
public void setName(String name) {
= name;
}
}非私有化属性的访问和修改:
public class Test02 {
public static void main(String[] args) {
Person p= new Person();
//读取非私有化属性
String address = p.address;
System.out.println(address);
System.out.println(p.address);
//修改非有化属性
p.address="三东";
System.out.println(p.address);
}
}
结果:null
null
三东私有化属性的读取和修改:
public class Test02 {
public static void main(String[] args) {
Person p= new Person();
="sss";//编译错误
}
}public class Test02 {
public static void main(String[] args) {
Person p= new Person();
//读取私有化属性
int age = p.getAge();
String name = p.getName();
System.out.print(age+" ");
System.out.print(name+" ");
System.out.print(p.getAge()+" ");
System.out.println(p.getName()+" ");
//修改私有化属性
p.setAge(10);
p.setName("张三");
System.out.print(p.getAge()+" ");
System.out.println(p.getName()+" ");
}
}
结果:0 null 0 null
10 张三注意:set和get方法只是两个普通的实例方法,名字是可以任意的,但是一般我们都是要满足set和get方法的书写规范。如以下例子:
但是访问权限一定不能是private.
public class Person {
//私有化属性
private int age;
public void age(int age){
this.age=age;
}
public int s(){
return age;
}
}public class Test02 {
public static void main(String[] args) {
Person p = new Person();
p.age(10);
System.out.println(p.s());
}
}
结果:10Java继承:
继承:属性继承(代码,空间的继承,数据的拷贝)
方法继承(访问权限)在不考虑多态的情况,静态也会被继承和可以重写
什么是继承?
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
Java继承是面向对象的最显著的一个特征。继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。
类和类之间的继承关系可以用UML符号表示,其中父类又叫超类或基类,子类又叫派生类。父类是子类的一般化,子类是父类的特化(具体化)。
继承的优点:
1.易维护性
java中继承可以通过增强一致性来减少模块间的接口和界面,可以增加了程序的易维护性。
2.复用性
java中继承可以提供程序的复用功能,可以减小代码和数据的冗余度,增加程序的重用性。
3.调理性
java中继承可以简化代码的复杂程度,能清晰体现相关类间的层次结构关系,使用代码的调理更加清晰。
继承的特性:
- Java中规定,子类继承父类,除了构造方法不能继承之外,剩下的都可以继承。但是私有属性无法在子类中直接访问。
- 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
- 子类可以用自己的方式实现父类的方法。
- Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 B 类继承 A 类,C 类继承 B 类,所以按照关系就是 B 类是 C 类的父类,A 类是 B 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。
- 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。
继承关键字:
继承可以使用 extends 和 implements 这两个关键字来实现继承,而且所有的类都是继承于 java.lang.Object,当一个类没有继承的两个关键字,则默认继承object(这个类在 java.lang 包中,所以不需要 import)祖先类。
1.extends关键字
在 Java 中,类的继承是单一继承,也就是说,一个子类只能拥有一个父类,所以 extends 只能继承一个类。
2.implements关键字
使用 implements 关键字可以变相的使java具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口(接口跟接口之间采用逗号分隔)。
代码示例:
extends
//父类
public class Person {
//非私有化属性
String gender;
//私有化属性
private int a=10;
//普通方法
public void see() {
System.out.println("看世界");
}
//get方法
public int getA(){
return a;
}
}
//子类
class Man extends Person{
}public class Test02 {
public static void main(String[] args) {
Man man = new Man();
//对非私有属性的继承
man.gender="男";
//对see方法的继承
man.see();
//对get方法的继承,和对私有化属性的继承
System.out.println(man.getA());
System.out.println(man.gender);
}
}
结果:看世界
10 男implements(此处不详细讲接口,只看继承(实现)的形式就可)
public interface Animal {
void eat();
}
interface 生命{
void run();
}
class Dog implements Animal,生命{
@Override
public void eat() {
System.out.println("吃饭");
}
@Override
public void run() {
System.out.println("快跑");
}
}public class Test03 {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat();
dog.run();
}
}
结果:吃饭
快跑方法的重写(覆盖):
方法的重写规则:
首先两个类必须有继承关系
- 参数列表与被重写方法的参数列表必须完全相同。
- 返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类(java5 及更早版本返回类型要一样,java7 及更高版本可以不同)。
- 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为 public,那么在子类中重写该方法就不能声明为 protected。
- 父类的成员方法只能被它的子类重写。
- 声明为 final 的方法不能被重写。
- 声明为 static 的方法不能被重写,但是能够被再次声明。
- 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 final 的方法。
- 子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 final 方法。
- 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
- 构造方法不能被重写。
- 如果不能继承一个类,则不能重写该类的方法
方法覆盖注意事项:
1,方法覆盖只针对方法,和属性无关。
2,私有方法无法覆盖
3,构造方法不能被覆盖(因为不能被继承)
4,方法覆盖只针对实例方法,静态方法覆盖没有意义
toString()方法:
toString ()方法是Java.lang包下的Object类的方法,而Object类是所有Java类的父类(所有类都继承了Object类)。也就是说每个类都有toString()方法。
1,toString ()方法有什么作用?
它是将”Java对象“转换成”字符串的形式“。
2,Object类中的toString ()方法的默认实现是什么?
public String toString(){
return getClass().getName() + "@" +Integer.toHexString(hashcode());
}这就是调用了Object中的toString()方法 ,这显然是达不到我们要求的(无法直观的看到我们所创建的对象,只能看到一串地址字符),所有我们一般会对Object中的toString()方法 进行重写。
public class Address {
String city;
}
class Test08{
public static void main(String[] args) {
Address address= new Address();
System.out.println(address.toString());
System.out.println(address);
}
}
结果:task02.Address@1540e19d
task02.Address@1540e19d重写过后:
1,
public class Address {
String city;
public String toString() {
return "city:"+city;
}
}
class Test08{
public static void main(String[] args) {
Address address= new Address();
System.out.println(address);
}
}
结果:city:null2.一般使用这种(看起来跟清晰)
public class Address {
String city;
@Override
public String toString() {
return "Address{" +
"city='" + city + '\'' +
'}';
}
}
class Test08{
public static void main(String[] args) {
Address address= new Address();
System.out.println(address.toString());
System.out.println(address);
System.out.println(address.city);
}
}
结果:Address{city='null'}
Address{city='null'}
nulltoString()方法是怎么被调用的呢?
让我们看下面的例子:
当我么要想看address时,想让程序员直观的看到,肯定是要转换成字符或字符串的。而toString()方法就是为了这个目的而出现的。当你使用"System.out.println(address)"语句时,其实会自动在address后面添加一个".toString()"。一般情况下我们是省略的。
而如果你不重写这个方法就会去父类找这个方法。(一定会有,顶级父类Object中有这个方法)
toString()是java中的一个内置方法,
其中"city"是Address类定义的一个属性,其对象为String,就会调用String类里面的toString()方法(String类中的toString()方法其实也是重写的Object中的方法,不详细将,会用就可以)
public class Address {
String city;
}
class Test08{
public static void main(String[] args) {
Address address= new Address();
System.out.println(address.toString());
System.out.println(address);
System.out.println(address.city);
}
}
结果:task02.Address@1540e19d
task02.Address@1540e19d
null
















