封装
将类中的信息进行隐藏,不允许在类外部访问(高内聚【类中将信息进行高度封装】低耦合【暴露少量方法给用户使用】)
如何封装
需要用到访问修饰符来进行代码的封装。
修饰符
- public:公开的,当前项目中的所有类中都可见
- protected:受保护的,在同一个包下或者在子类中可见。
- [default]:不加访问修饰词时,表示默认访问权限,同一包可见
- private:私有的,只在当前类中可见
当前类 | 同一包 | 不同包 子类 | 其他类 | |
---|---|---|---|---|
public | √ | √ | √ | √ |
protected | √ | √ | √ | X |
[default] | √ | √ | x | X |
private | √ | X | X | X |
封装的应用
person.java
public class Person {
private String name;
private int age;
//getter,setter:用于操作被封装的属性
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
//防止输入有误添加限制
if(age>=18 && age<=50){
this.age = age;
}else{
System.out.println("输入的年龄有误,年龄区间【18-50】默认18");
this.age=18;
}
}
public void show(){
System.out.println("姓名:"+name+":"+"年龄"+age);
}
/**
* 如果num为1,表示要学习java,如果num 为2,表示要学习数据库
* @param num
*/
public void study(int num){
if(num==1){
studyJava();
}else if(num==2){
studyDB();
}
}
//private 私有化方法只在类内部调用,提供了study公有方法内部封装studyDB,studyJava
private void studyDB() {
System.out.println(this.name+"正在学习数据库");
}
private void studyJava() {
System.out.println(this.name+"正在学习java");
}
}
TestPerson.java
public class TestPerson {
public static void main(String[] args) {
Person person=new Person();
person.setName("张杰");
person.setAge(25);
person.show();
person.study(2);
}
}
/*
姓名:张杰:年龄25
张杰正在学习数据库
*/
继承
管理类和类之间的关系。减少代码的重复,可以使用继承。可以对父类进行扩展。
继承可以实现代码的重用,类是对对象的抽象,继承是对一部分代码的抽象。实现继承,需要使用一个关键字extends
继承的特点
被继承的类:父类,基类,超类
继承别的类:子类衍生类
父类的成员变量和方法可以被继承,构造器不能被继承。(名字)
继承可以实现代码的复用,降低代码的冗余
构造器不能被继承,但是可以通过super调用父类的构造器
this 和super
- this代表当前类的对象的引用,super代表父类对象的引用
- this 可以用于调用成员变量和方法,super 可以用于调用父类的成员变量和方法
- this 在构造器中可以被用于调用当前类的其他构造器,必须写在第一行,super 在构造器中可以被用于调用父类的方法和成员变量。必须写在第一行。
- this 和super 不能同时使用
Person.java
/**
* 被继承的类,称之为父类;基类,超类
* @author lenovo
*
*/
public class Person {
private String name;
private int age;
//构造器
public Person(){
}
public Person(String name,int age){
this.name=name;
this.age=age;
}
public void show(){
System.out.println("姓名:"+name+":"+"年龄"+age);
}
}
Teacher.java
/**
* 通过extends 关键字可以实现类的继承关系
* 子类可以对父类进行扩展
* @author lenovo
*
*/
public class Teacher extends Person{
double salary;//工资
//构造器
/*public Teacher(){
}*/
/**
* super关键字,代表父类的对象的引用,super()表示引用父类构造器
* 默认情况下,子类构造器,java会在构造器中开头默认加一个super()
* 如果自己调用了父类的其他构造器,那么就不会调用父类的无参构造器了
* @param name
* @param age
* @param salary
*/
public Teacher(String name, int age, double salary) {
super(name,age);
this.salary = salary;
}
public void showSal(){
System.out.println("工资"+salary);
}
方法的重载overload :方法名相同,参数 列表不同(参数类型,参数个数,参数顺序)
方法重写
出现在继承中,overwrite 子类方法对父类方法进行扩展的情况被称之为方法的重写。
重写特点:
- 子类重写:方法同名,同返回值类型,参数列表,访问修饰符的范围要大于等于父类访问修饰符的范围
- 可以使用super().方法名进行调用
- 子类一旦重写父类方法父类方法将不再使用
- 重写的好处:可以在父类方法功能的基础 进行拓展,提高了程序的可扩展性
/**
* 通过extends 关键字可以实现类的继承关系
* 子类可以对父类进行扩展
* @author lenovo
*
*/
public class Teacher extends Person{
double salary;//工资
//构造器
public Teacher(){
}
/**
* super关键字,代表父类的对象的引用,super()表示引用父类构造器
* 默认情况下,子类构造器,java会在构造器中开头默认加一个super()
* 如果自己调用了父类的其他构造器,那么就不会调用父类的无参构造器了
*/
public Teacher(String name, int age, double salary) {
super(name,age);
this.salary = salary;
}
public void showSal(){
System.out.println("工资"+salary);
}
public void show(){
System.out.println("这是子类中的show方法");
super.show();
System.out.println("=========");
}
}
Object类
在java中,Object l类是所有类的直接或者间接父类。顶级父类。
Object 中提供的几个方法
- toString():将对象转换为字符串,当打印对象时,默认会调用toString 方法。自定义类型中,我们可以重写toString 方法,从而方便对象的打印
- equals(java.lang.Object arg0)
Demo.java
public class Demo {
private int a;
private String b;
public Demo(){}
public Demo(String b,int a){
this.a=a;
this.b=b;
}
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + a;
result = prime * result + ((b == null) ? 0 : b.hashCode());
return result;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Demo other = (Demo) obj;
if (a != other.a)
return false;
if (b == null) {
if (other.b != null)
return false;
} else if (!b.equals(other.b))
return false;
return true;
}
/*public boolean equals(Object obj) {
Demo d =(Demo)obj;
if(this==obj){
return true;
}
if(this.a!=d.a){
return false;
}else if(this.b.equals(d.b)){
return true;
}
return false;
}*/
}
TestDemo.java
public class TestDemo {
public static void main(String[] args) {
Demo demo=new Demo("asda",12);
Demo demo2=new Demo("asda",12);
System.out.println(demo==demo2);
System.out.println(demo.equals(demo2));//默认false 重写equals后true
}
}
多态
一个类可以多种形态。提高代码的可扩展性。
多种形态:对象的类型在编译阶段类型不固定。在运行阶段才能够确定类型
引用数据类型类型的转换
public class Test {
public static void main(String[] args) {
Person person=new Person("张三",18);
Teacher teacher=new Teacher("李四",20,30000);
//引用类型的类型转换,分两种情况
//小类型转大类型---》向上转型
//大类型转小类型----》向下转型
//小类型转大类型---》向上转型
//将子类型转换成父类型,子类型中独有的方法将不能用
Person p=teacher;
p.show();
//大类型转小类型----》向下转型
//可以使用instanceof 关键字判断类型,用于查看某个对象是否是某个类型的对象
/*Teacher t=(Teacher)person;
t.show();
t.showSal();*/
Person p2=teacher;//先向上转型
Teacher t=(Teacher)p2;
t.show();
t.showSal();
}
}
多态的应用
person.java
public class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Person(){}
public Person(String name){
this.name=name;
}
public void show (){
System.out.println("姓名:"+name);
}
}
chinese.java
public class Chinese extends Person {
private String loc;
public Chinese() {
super();
}
public Chinese(String name,String loc) {
super(name);
this.loc=loc;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
public void taiji (){
System.out.println(this.getName()+"打了一套太极拳。。。");
}
}
American.java
public class American extends Person {
private String xinzuo;
public American() {
super();
}
public American(String name,String xinzuo) {
super(name);
this.xinzuo=xinzuo;
}
public String getXinzuo() {
return xinzuo;
}
public void setXinzuo(String xinzuo) {
this.xinzuo = xinzuo;
}
public void drinkCoffe(){
System.out.println(this.getName()+"喝了一杯咖啡");
}
}
company.java
public class Company {
/**
* 招聘方法,使用多态可以解决这个问题:定义方法过多
*/
public void findPerson(Person person){
System.out.println("公司招到一个新员工");
person.show();
//才艺表演
if(person instanceof Chinese){
Chinese c=(Chinese) person;
c.taiji();
}else if(person instanceof American){
American a=(American)person;
a.drinkCoffe();
}
}
}
Test.java
public class Test {
public static void main(String[] args) {
Company company = new Company();
Person person=new Chinese("张杰","狗");//向上转型
company.findPerson(person);
}
}
总结
什么时候会发生多态?(发生多态的前提)
必须要有继承关系,
发生类型转换:向上转型,向下转型
方法调用:子类对象可以调用父类中的方法
父类对象可以调用子类的方法
多态的好处
类型在编译阶段只是父类,运行阶段可以是任意的子类型,简化方法的重载,
方便代码的扩展,