面向对象的三大特性
封装
1.封装的概念就是要使程序**“高内聚,低耦合”**
- 高内聚:就是类的内部数据操作细节自己完成,不允许外部干涉
- 低耦合:仅暴露少量的方法给外部使用
2.封装就是禁止直接访问一个对象中数据的实际表示,而通过操作接口来访问**(get/set)**
package com.oop.demo03;
//学生类 private:私有的
public class Student {
//属性私有
private String name;//姓名
private int id;//学号
private char sex;//性别
private int age;//年龄
//通过提供一些public get、set方法使程序可以被调用
//get :获得这个数据
public String getName(){
return this.name;
}
//set :给这个数据设置值
public void setName(String name){
this.name=name;
}
//使用快捷键:Alt+insert可以快速生成get、set方法
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
//可以在set方法中加入判断语句,使程序更加严谨
switch (sex){
case '男': this.sex = sex;
break;
case '女': this.sex = sex;
break;
default: this.sex = '无';;
break;
}
}
public int getAge() {
return age;
}
public void setAge(int age) {
if(age>0 && age<100){
this.age = age;
}else{this.age=0;}
}
}
封装的意义
1.提高程序的安全性,保护数据
2.隐藏代码的实现细节
3.统一接口
4.提高了系统的可维护性
public class Application {
public static void main(String[] args) {
Student s1 = new Student();
//使用private为修饰符时,程序不能直接被调用
s1.setName("浩鑫");
s1.setId(1001);
s1.setSex('男');
s1.setAge(101);
System.out.println(s1.getName());
System.out.println(s1.getId());
System.out.println(s1.getSex());
System.out.println(s1.getAge());
}
}
继承
-
继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模
-
extends的意思是扩展,子类是父类的扩展
-
java中类只有单继承没有多继承
-
继承是类和类之间的关系。除此之外,类和类之间的关系还有依赖,组合,聚合等。
-
继承关系有两个类,一个为子类(派生类),一个为父类(基类),子类继承父类,使用关键字“exrtends”来表示
//人 类-->父类/基类 //Java中的所有类都直接或者间接继承Object类 public class Person { //1.public:公共的 //2.protected:受保护的 //3.default:违约的 //4.private:私有的 private int money=10_0000_0000; public void say(){ System.out.println("说了一句话"); } public int getMoney() { return money; } public void setMoney(int money) { this.money = money; } }
//学生 is 人 学生类(子类/派生类)继承人类(父类/基类)
//子类继承父类,他就会拥有父类的全部方法
//使用ctrl+h 可以查看所在类的子类及父类
public class Student extends Person {
}
package com.oop.demo04;
//老师 is 人 老师类(子类/派生类)继承人类(父类/基类)
public class Teacher extends Person {
}
import com.oop.demo04.Student;
import com.oop.demo04.Teacher;
//测试类
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.say();说了一句话
System.out.println(student.getMoney());1000000000
Teacher teacher = new Teacher();
teacher.say();说了一句话
System.out.println(teacher.getMoney());1000000000
}
}
super与继承的关系
package com.oop.demo04;
//父类
public class Person {
public Person() {
System.out.println("person无参");
}
protected String name="浩鑫";
//私有的东西无法被继承
public void print(){
System.out.println("Person");
}
}
package com.oop.demo04;
//子类
public class Student extends Person {
public Student() {
//隐藏代码:默认先调用父类的无参构造
super();
//调用父类的构造器,必须要在子类构造器的第一行
System.out.println("student无参");
}
private String name="Andy";
public void print(){
System.out.println("Student");
}
public void test2(){
print();
this.print();
//通过super可以调用父类中的方法
super.print();
}
public void test1(String name){
System.out.println(name);
System.out.println(this.name);
//通过super可以调用父类中的属性
System.out.println(super.name);
}
}
package com.oop;
import com.oop.demo04.Student;
public class Application {
public static void main(String[] args) {
Student student = new Student();//
//person无参
//student无参
student.test1("hao");
//hao
//Andy
//浩鑫
student.test2();
//Student
//Student
//Person
}
}
/*
super注意点
1.super调用父类的构造方法必须在构造方法的第一个
2.super必须只能出现在子类的方法或构造方法中
3.super和this不能同时调用构造方法
vs this:
代表的对象不同
super:代表的是父类对象的应用
this:代表的是本身调用的这个对象
前提条件不同
this:没有继承也可以使用
super:只能在继承条件下才能使用
构造方法不同
this();本类的构造
super();父类的构造
*/
方法的重写与继承的关系
package com.oop.demo04;
//父类
//重写都是方法的重写,与属性无关
public class Person {
public void test(){
System.out.println("Person=>test()");
}
}
package com.oop.demo04;
//子类
public class Student extends Person {
//Override:重写的意思
@Override//这个是注解 有功能的注释
public void test() {
System.out.println("Student=>test()");
}
}
package com.oop;
//测试类
import com.oop.demo04.Person;
import com.oop.demo04.Student;
public class Application {
public static void main(String[] args) {
静态方法和非静态的方法区别很大
静态方法:方法的调用只和左边定义的数据类型有关
非静态方法:能实现重写
Student student = new Student();
student.test();//Student=>test()
//父类的引用指向子类
Person person=new Student();
person.test();//Student=>test()
}
}
/*
重写
1.重写需要有继承关系,而且只能子类重写父类的方法
2.方法名必须相同
3.参数列表必须相同
4.修饰符可以被扩大但不能缩小 public>protected>default>private
5.抛出的异常:范围可以被缩小但不能扩大: classNotFountException-->Exception(大)
6.方法体必须不同
7.重写的快捷键:Alt+Insert-->Override;
*/
多态
- 即同一个方法可以根据发送对象不同而采用多种不同的行为方式
- 一个对象的实际类型是可以确定的,但可以指向的引用类型有很多
- 多态的存在条件
- 有继承关系
- 子类重写父类的方法
- 父类引用指向子类的对象
注意点:多态是方法的多态,属性没有多态
package com.oop.demo05;
//父类
public class Person {
public void run(){
System.out.println("run");
}
}
package com.oop.demo05;
//子类
public class Student extends Person {
@Override
public void run() {
System.out.println("son");
}
public void eat(){
System.out.println("eat");
}
}
package com.oop;
//测试类
import com.oop.demo05.Person;
import com.oop.demo05.Student;
public class Application {
public static void main(String[] args) {
//一个对象的实际类型是可以确定的
//new Student();
//new Person();
//可以指向的引用类型是不确定的。父类的引用指向子类
//Student 能调用的方法都是自己的或继承父类的
Student s1 = new Student();
//Person 父类型 可以指向子类,但无法调用子类独有的方法
Person s2 = new Student();
Object s3 = new Student();
//对象能执行什么方法主要看对象左边的引用类型,和右边关系不大
s1.run();
s2.run();//子类重写了父类的方法,执行了子类的方法
//父类无法直接调用独有的方法
s1.eat();
}
}
*/
/*
多态的注意事项
1.多态是方法的多态,属性没有多态
2.多态必须有继承关系,父类和子类,否则报类型转换异常:ClassCastException
3.存在的条件
继承关系
方法需要重写
父类的引用指向子类
注意点:哪些方法不能被重写
1.static(静态的)方法:属于类,它不属于实例
2.修饰符为final(常量)
3.修饰符为private(私有的)
*/
instanceof和类型转换
package com.oop;
import com.oop.demo06.Person;
import com.oop.demo06.Student;
import com.oop.demo06.Teacher;
public class Application {
public static void main(String[] args) {
//instanceof是用来判断两个对象之间是否存在父子关系,
//object>string
//object>person>Teacher
//object>person>student
Object object = new Student();
System.out.println(object instanceof Student);//true
System.out.println(object instanceof Person);//true
System.out.println(object instanceof Object);//true
System.out.println(object instanceof Teacher);//false
System.out.println(object instanceof String);//false
System.out.println("==========================");
Person person = new Student();
System.out.println(person instanceof Student);//true
System.out.println(person instanceof Person);//true
System.out.println(person instanceof Object);//true
System.out.println(person instanceof Teacher);//false
//System.out.println(person instanceof String);//编译就报错了
//两个对象不存在联系,那么编译就会直接报错
System.out.println("==========================");
Student student = new Student();
System.out.println(student instanceof Student);//true
System.out.println(student instanceof Person);//true
System.out.println(student instanceof Object);//true
//System.out.println(student instanceof Teacher);//编译就报错了
//System.out.println(person instanceof String);//编译就报错了
//两个对象不存在联系,那么编译就会直接报错
System.out.println("==========================");
}
}
package com.oop.demo06;
//父类
public class Person {
public void run(){
System.out.println("run");
}
}
package com.oop.demo06;
//子类
public class Student extends Person {
public void go(){
System.out.println("go");
}
}
package com.oop;
import com.oop.demo06.Person;
import com.oop.demo06.Student;
import com.oop.demo06.Teacher;
public class Application {
public static void main(String[] args) {
//类型转换 父类>子类
//高 低 低转高:自动转换
Person person = new Student();
//将person对象转换为Student类型,这样就可以使用Student类型的方法
((Student)person).go(); //高转低:强制转换
Student student = new Student();
//低转高,子类转换成父类
Person person1=student;//子类转换成父类可能会丢失子类自己本身的一些方法
}
}
/*
总结
1.父类的引用指向子类的对象
2.把子类转换成父类,向上转型(自动转换)
3.把父类转换成子类,向下转型(强制转换)
4.类型转换可以方便方法的调用,减少重复的代码,使代码更加简洁
*/