面向对象语言的三大特征
封装
包装 把实现细节包装起来,对外提供方法访问
将类中的某些信息或者成员方法隐藏起来,外部无法直接访问,向外提供一些专门的方法操作;
隐藏(访问权限修饰符)
public class Person {
/**
通过访问修饰符来隐藏类中的信息
*/
private String name;
private int age;
/* public Person(String n , int a){k
name = n;
age = a;
}*/
/**
*为私有属性提供专门的方法来进行访问
* this 现实的表示当前正在访问的对象
*/
public void setName(String name) {
if (name.length() < 5) {
this.name = name;//对象p访问时,this表示的是p对象
eat();
}else{
this.name="肖恩";
this.eat();//本类中访问私有权限的方法
}
}
public String getName(){
return name;
}
public void setAge(int age){
this.age=age;
}
public int getAge(){
return age;
}
/*
私有权限的方法,可以在本类中访问
*/
private void eat() {
System.out.print("干饭王:");
}
}
public class PersonTest {
public static void main(String[] args) {
/*Person p = new Person("jim",20);*/
/*Person p1 = new Person("jack",28);*/
Person p = new Person();
p.setName("崔");
p.setAge(21);
System.out.println(p.getName()+p.getAge());
Person p1 = new Person();
p1.setName("瑞");
p1.setAge(22);
System.out.println(p1.getName()+p1.getAge());
}
}
this关键字
this关键字代表自身类的对象
注意:this关键字必须放在非静态方法里面
public class Demo{
private int a;
public Demo(int a){
this.a = a;
}
public int getA(){
return a;
}
public void setA(int a){
this.a = a;
}
}
继承
- 父类被子类继承
- 子类可以拥有父类的一些功能
- 继承是面向对象语言的一种设计思想
- 可以提高代码的重用性以及代码的可扩展性
举个例子
人类:共有姓名属性
学生类:继承人类 自有属性:学号
小学生:继承学生类
中学生:继承学生类
大学生:继承学生类
工人类:继承人类 自有属性:工号 工种
什么样的关系可以使用继承?
同一类的东西( is a 关系)
A类 extends Object{}
B类 extends A类{}
C类 extends B类{}
创建父类(People)
package com.ff.javaopp.Day004;
/*
primarySchool类继承People
PrimarySchool是People的子类(派生类)
父类(基类)
把人类相关的一些公有属性,行为,定义在people类中
extends关键字
当一个类没有显示的继承一类,那么这个类默认继承object
object是java所有类的基类 称超类
*/
public class People {
private String name ;
private int age;
public People(){
System.out.println("人类中的无参的构造方法");
}
public People(String name){
this.name=name;
System.out.println("人类中的有参的构造方法");
}
public void setName(String name ){
this.name=name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
public void eat(){
System.out.println(name+"干饭人,干饭魂,干饭都是人上人");
}
}
创建子类(PrimarySchool)
public class PrimarySchool extends People {
private String clas;
public PrimarySchool(){
super("小红");
System.out.println("小学生中的无参构造方法");
}
public void setClass(String clas){
this.clas=clas;
}
public String getClas(){
return clas;
}
public void play(){
System.out.println("过家家");
}
}
创建子类(MiddleSchool)
public class MiddleSchool extends People{
private String grade;
public void study(){
System.out.println("学习人,学习魂,学习都是人上人");
}
public void setGrade(String grade){
this.grade=grade;
}
public String getGrade(){
return grade;
}
}
创建测试类(PeopleTset)
package com.ff.javaopp.Day004;
public class PeopleTset {
public static void main(String[] args) {
PrimarySchool p = new PrimarySchool();
p.setName("瑞瑞");//父类
p.setAge(21);//父类
p.setClass("学前班");//小学生自己的属性
System.out.println(p.getName()+p.getAge());//父类
System.out.println(p.getClas());//小学生自己的属性
p.eat();//父类
p.play();//小学生自己的方法
MiddleSchool M = new MiddleSchool();
M.setName("荣荣");//父类
M.setAge(22);//父类
M.setGrade("高中生");//高中生自己的属性
System.out.println(M.getName()+M.getAge());//父类
System.out.println(M.getGrade());//高中生自己的属性
M.study();//高中生自己的属性
M.eat();//父类
p.hashCode();//调用object类中的方法
/*
子类继承了父类后,可以拥有父类中私有属性,方法
*/
}
}
在创建子类对象时,会先调用父类构造方法,创建父类对象
public class Test {
/*
继承中的构造方法
在创建一个子类对象时,同时也会创建父类对象
*/
public static void main(String[] args) {
XiaoMing xm= new XiaoMing();
xm.eat();
}
}
super表示父类
super关键字代表父类的引用,在程序中主要的用途
在子类构造方法中要调用父类的构造方法,需要注意:super语句只能出现在子类构造方法体的第一行。
用“super.成员变量名”来引用父类成员变量
用“super.方法名(参数列表)”的方式访问父类的方法。
与this的区别,this通常指代当前对象,super通常指代父类。
创建小学生(PrimarySchool)的子类(XiaoMing)
public class XiaoMing extends PrimarySchool{
/*
在调用子类方法时,会先调用父类的构造方法
*/
public XiaoMing(){
//super(); 构造方法第一行默认使用super();调用父类默认无参的构造方法
super();//需要显示调用,必须放在构造方法的第一行
System.out.println("小学生小明中无参的构造方法");
}
}
方法的重写
为什么使用方法的重写?
父类的实现方式不能满足子类的功能时可以进行重写
public class XiaoMing extends PrimarySchool{
/*
方法的重写:当子类中的实现步骤与父类中的实现方式不同时,
可以在子类中将父类中的方法重写
必须与父类的方法结构相同(返回值,参数)
子类重写后的方法的权限范围要大于等于父类方法的访问权限
super表示当前类的父类对象
在子类中可以通过super访问父类中成员
@Override 注解 标签
表明该方法是从父类中重写过来了的
*/
@Override
public void eat(){
System.out.println("小明喜欢吃面面");
super.eat();//调用父类成员
}
public void Question(){
System.out.println("小学生小明喜欢问问题");
}
}
了解关联关系和依赖关系
创建一个Mobile类
public class Mobile {
private String num;
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
}
关联关系:has-a关系 XXX有XXX
依赖关系:use-a关系 某个类中用到另一个类
public class Person {
private Mobile mobile;//单向关联 一对一关联
private Mobile[] mobiles;//单项关联 一对多关联
/*
依赖关系,Person中的某个方法中使用到另一个类
*/
public void callPeople(MiddleSchool middleSchool){
middleSchool.study();
middleSchool.setAge(25);//传递过来的是引用类型,会改变原来的值
}
}
抽象类abstract
- 如果一个类中没有包含足够的信息来描述一个具体的对象,这样的类就是抽象类
- 抽象类 也是一个类
- 抽象方法:被abstract关键字修饰,没有方法体,只是作为功能的定义
抽象类的特点:
不能创建对象,因为其中包含了抽象的方法
包含构造方法,在创建子类对象时,可以简介创建父类对象
创建Animal类
/*
被abstract修饰的类就是抽象类
抽象类中不一定有抽象方法
有抽象方法,那么这个类必定是抽象类
*/
public abstract class Animal {
String name;
/*
在顶层类中,方法的实现与子类大多不相同,那么在顶层类中可以将方发声明为抽象方法
被abstract修饰,没有方法体
只作为方法的定义
*/
public abstract void eat();
public abstract void sleep();
public void play(){
System.out.println("Animal Play");
}
}
创建子类Dog类
/*
抽象类就是作为定义,让其他类继承
一个类继承抽象类:
要么将子类声明为抽象类
要么重写抽象类中所有的抽象方法
*/
public class Dog extends Animal{
@Override
public void eat() {
System.out.println("狗子吃");
}
@Override
public void sleep() {
System.out.println("狗子睡");
}
}
创建子类Cat类
package com.ff.javaopp.Day004.abstractDemo;
public class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫吃鱼");
}
@Override
public void sleep() {
System.out.println("猫睡觉");
}
}
创建测试类
package com.ff.javaopp.Day004.abstractDemo;
public class Test {
public static void main(String[] args) {
Dog d = new Dog();
d.eat();
d.sleep();
d.play();
}
多态
同种事物,在不同时刻表现不同的状态
多态的条件:
- 要有继承
- 要有方法重写
- 父类的引用指向子类对象
不使用多态
public class Test {
public static void main(String[] args) {
/* Dog d = new Dog();
d.eat();
d.sleep();
d.play();*/
//Dog d = new Dog();不是多态
Dog dog = new Dog();
Cat cat = new Cat();
Test t = new Test();
t.feedCat(cat);
t.feedDog(dog);
}
public void feedDog(Dog dog) {
dog.eat();
dog.sleep();
}
public void feedCat(Cat cat) {
cat.eat();
cat.sleep();
}
}
代码过于冗余
使用多态
public class Test1 {
public static void main(String[] args) {
Animal dog = new Dog();
//dog.eat();编译期间看左边,运行期间看右边
Animal cat = new Cat();
Test1 t = new Test1();
t.feedAnimal(cat);
t.feedAnimal(dog);
}
public void feedAnimal(Animal animal) {
animal.eat();//
animal.sleep();
}
}
运行结果:
猫吃鱼
猫睡觉
狗子吃
狗子睡