面向对象学习4. 面向对象三大特征
- 1封装:高内聚(内部细节自己用,外部不能介入),低耦合(保留很少接口给外部使用),信息隐藏(禁止外界直接访问内部数据(private),如需要,可通过get/set接口访问)(method get/set下面有详细说明)
- 2继承
- 3多态
封装详解
面向对象学习5. 抽象类和接口
private/get/set详细说明:
实际操作中 class内部不是经常用public String def_name而是经常用 private String def_name;
但private的数据不可获取,解决方案是利用自建public get/set method下面新建变量,连接private变量,这样就能保证内部的加密性和模块固定完整性了。
比如在main里面新建一个my_class类型的object叫做x
my_class x = new my_class();
然后给x赋值,注意到my_class本身是公开的public class my_class{}
,但是其内部的接口全是private的,类似private String int_name;
无法直接在main内调用int_name的值。
解决方案:
my_class类型下面加public get/set method
大概结构原理类似这样
public class my_class{
private String int_name;
public String get_name{return int_name;}
public void set_name(String io_name){this.int_name=io_name;}
}
具体代码如下
public class testjan05{
public static void main(String args[]) {
my_class x = new my_class();
//新建object
//为non_s类型(需要按照non_s的class类型制作)
//这个object取名叫做x
x.set_name("Emma");
//执行x里面的method方法set_name,
//并给了一个叫做Emma的输入值
System.out.println(x.get_name());}
//打印输出x下的method方法get_name的返回值
}
//这是对应的my_class文件
public class my_class {
private String int_name;
public void set_name(String io_name) {
this.int_name = io_name;
}
//io_name是能够连接外部接口的公开接口
//int_name是my_class内部的private接口
public String get_name() {
return int_name;
}
//外部需要int_name信息的时候,int_name是private无法调用
//就想办法调用public的method get_name即可
}
输出为
Emma
快捷键
IDEA 自动生成Get/Set模块
Alt+insert(AUUS电脑可能需要额外再按Fn键)
按下之后选择Getter或者Setter即可获得所想要的接口模块(如上图所式)
代码举例
package oop;
//import oop.Demo03.pet;
import oop.Demo04.Student;
public class Application {
/*
public static void main(String[] args) {
pet doggy =new pet();
doggy.name="wangcai";
doggy.age =3;
doggy.shout();
System.out.println(doggy.name);
System.out.println(doggy.age);
System.out.println();
}
*/
public static void main(String[] args) {
Student x = new Student();
x.setName("Ella");
x.setAge(33);
System.out.println(x.getName());
System.out.println(x.getAge());
}
}
package oop.Demo04;
public class Student {
private String name;
private int age;
private int id;
public String getName() {
return this.name;
}
public int getAge() {
return age;
}
public int getId() {
return id;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int def_age) {
if (def_age <0 || def_age >120)
this.age=3;
else
this.age = def_age;
}
public void setId(int id) {
this.id = id;
}
}
运行运行结果
Ella
33
get/set method的存在,可以帮助程序员在不改变内部结构的前提下,对代码控制维护
比如下面的例子,增加了age并且对输入的age范围控制为0-120,否则赋值666
public class testjan05{
public static void main(String args[]) {
non_s x = new non_s();
x.set_name("Lisa");
System.out.println(x.get_name());
x.setInt_age(166);
System.out.println(x.getInt_age());
}
}
public class non_s {
private String int_name;
private int int_age;
public void set_name(String io_name) {
this.int_name = io_name;
}
public String get_name() {
return int_name;
}
public void setInt_age(int io_age) {
if (io_age >= 0 && io_age <= 120)
this.int_age = io_age;
else this.int_age=666;
}
public int getInt_age() {
return int_age;
}
}
总结:封装接口的作用
- 提高代码的安全性
- 隐藏代码的实现细节
- 统一接口
- 增加系统的可维护性
补充知识点:方法的重载
- 思考:为什么println(x)可以输出很多不同种类的x呢?
比如x可能是char int float String为什么println都能直接输出呢?
在IDEA里面找到一处出现println的地方,按住ctrl键,跳转到println的源码,会发现,源码将能想到的各种input全类型囊括了,一项写一个method。
这些定义的method全部都叫println,他们是同名的,但是他们每一个method定义的输入类型都是不同的。
继承
继承用于class之间。先学一个关键词extends
extends表示继承 扩展,Class kids extends Class human
子类kids继承了父类human的属性
- 问题:什么是object class?
先说结论:在java中,全体class代码都默认继承Object class
在java中 class相当于样板,新建的object需要根据对应的class样板来依葫芦画瓢。而所有自建的class都有一个共同的“爸爸”它就是Object class注意这个“Object”首字母是大写的。
- 验证Object class的存在(在IDEA中):
打开Hierarchy模块
在IDEA里面打开View/Tool Window/Hierarchy可以在屏幕右侧看到Hierarchy模块,默认已经选中了当前的文件,可以看到它是在一个叫public class Object的文件结构下列着
如果还想查看其他的文件,选中一个文件比如Application,然后快捷键Ctrl+H即可打开hierarchy window里看到对应的结构信息
可以看到 最上面通通都有一个Object字样。
结论 在java中,全体class代码都默认继承Object class
注意只有单继承,没有多继承。一个儿子class只能有一个爸爸class,但是一个爸爸class可以有多个儿子class。
使用方法
public class kids extends human{
//表明kids class继承了human class的全部功能模块和其变量&值
//kids本身是空的
}
public class human {
public static void talk() {
System.out.println("小嘴巴巴说个不停");
}
public static int valuables() {
//public 换成 private 就不能被继承了,如果调用就会报错
//如果不写,默认为public
int money = 1_000_000_000;
return money;
}
}
public class testjan05{
public static void main(String args[]) {
kids x = new kids();
//新建一个kids类型的object叫做x,样本从kids class那里来
x.talk();
//调用x object里面的talk method
//注意kids类型本身是空的,talk method能用,只可能是从human class那里继承的
System.out.println(x.valuables());
}
}
程序运行结果:
小嘴巴巴说个不停
1000000000
想要子类继承 那必须是public的,一旦设置为private,继承并且使用的子类马上会报错。 默认的四个属性修饰符为public/private/default/protected
如果想要使用内部private的变量,那么可以自定义前面介绍过的get/set method进行获得再使用。
比如对刚才的例子进行修改
public class human {
public static void talk() {
System.out.println("小嘴巴巴说个不停");
}
private int money=6_00_000_000;
//注意这里的money已经变成private了。卖年里面之前的调用方法不合适了
public int getMoney() {
return money;
}//这里创建public getMoney method,
//成功将class内部private的money变量通过public method getoney的return引出
}
kids程序除继承语句仍为空,main主程序如下
public class testjan05{
public static void main(String args[]) {
kids x = new kids();
x.talk();
//System.out.println(x.valuables());
System.out.println( x.getMoney());
}
}
最后运行结果
小嘴巴巴说个不停
600000000