java基础面向对象_Java基础之面向对象

1.面向对象

面向对象的三大特性:封装性、继承性、多态性

封装

1.方法就是一种封装

2.关键字private也是一种封装

封装就是将一些细节信息隐藏起来,对于外界不可见

packagecom.dcits.day05.demo03;

​public classDemo02Method {public static voidmain(String[] args) {int[] array = {5,15,25,35,111};int max =getMax(array);

System.out.println(max);

}public static int getMax(int[] array) {int max = array[0];for (int i = 0; i < array.length; i++) {if (array[i] >max) {

max=array[i];

}

}returnmax;

}

}

private关键字的作用以及使用

一旦使用了private进行修饰,那么本类中可以随意访问,但是超出了本类的范围就不能再访问了

可以通过间接访问的方式,自定义一对儿Getter/Setter方法,必须叫 setXxx 或者是 getXxx

对于Getter来说,不能有参数,返回值类型和成员变量对应

对于Setter来说,不能有返回值,参数类型和成员变量对应

//Person类

packagecom.dcits.day05.demo03;

​public classPerson {

String name;private intage;public voidshow() {

System.out.println("我叫:" + name +",今年" +age);

}public void setAge(intnum) {if (num < 100 && num >=9) {

age=num;

}else{

age= 0;

System.out.println("数据不合理");

}

}public intgetAge() {returnage;

}

}

​//调用

packagecom.dcits.day05.demo03;

​public classDemo03Person {public static voidmain(String[] args) {

Person person= newPerson();

person.name= "赵丽颖";//person.age = 18; 当成员变量被private修饰的时候,外部无法访问,只能通过间接的方式Setter,Getter

person.setAge(-20);

person.show();

}

}

布尔类型的特殊情况

//类

packagecom.dcits.day05.demo03;

​public classStudent {privateString name;private intage;private booleanmale;

​public void setMale(booleanb){

male=b;

}public booleanisMale() {returnmale;

}

​public voidsetName(String str){

name=str;

}publicString getName() {returnname;

}public void setAge(intnum) {

age=num;

}public intgetAge() {returnage;

}

}//调用

packagecom.dcits.day05.demo03;

​public classDemo04Student {public static voidmain(String[] args) {

Student stu= newStudent();

stu.setName("alex");

stu.setAge(10);

stu.setMale(true);

System.out.println(stu.getName());

System.out.println(stu.getAge());

System.out.println(stu.isMale());

}

}

this关键字的使用

当方法的局部变量和类的成员变量重名的时候,根据就近原则,优先使用局部变量,如果需要访问 本类当中的成员变量,需要使用格式:this.成员变量

通过谁调用的方法,谁就是this

//类

packagecom.dcits.day05.demo04;

​public classPerson {

String name;public voidsayHi(String name) {

System.out.println(this.name + "你好,我是" +name);

}

}//调用

packagecom.dcits.day05.demo04;

​public classDemo01Person {public static voidmain(String[] args) {

Person person= newPerson();

person.name= "6666";

person.sayHi("777");

}

}

构造方法

构造方法是专门用来创建对象的方法,当我们使用关键字new来创建对象的时候,其实就是在调用构造方法

注意事项:

构造方法的名称必须和所在的类名称完全一样,就连大小写也要完全一样

构造方法不要写返回值类型,连void都不要写

构造方法不能return一个具体的返回值

如果没有编写任何构造方法,那么编译器默认会赠送一个构造方法,没有参数、方法体什么都不做

一旦编写了一个构造方法,那么编译器就不再赠送

构造 方法也是可以重载的

//类

packagecom.dcits.day05.demo04;

​public classStudent {privateString name;private intage;public Student(String name,intage) {this.name =name;this.age =age;

System.out.println("有参数的构造方法!!");

}publicStudent() {

System.out.println("无参数的构造方法执行啦!!");

}public voidsetName(String name) {this.name =name;

}publicString getName() {returnname;

}public void setAge(intage) {this.age =age;

}public intgetAge() {returnage;

}

}//调用

packagecom.dcits.day05.demo04;

​public classDemo02Student {public static voidmain(String[] args) {

Student stu= newStudent();

Student stu1= new Student("aaa",20);

stu1.setAge(23);

System.out.println(stu1.getAge());

System.out.println(stu1.getName());

}

}

局部变量和成员变量

定义的位置不一样

局部变量:在方法的内部

成员变量:在方法的外部,直接写在类当中

作用范围不一样

局部变量:只有方法 才可以使用,出了方法就不能再使用了

成员变量:整个类都可以通用

默认值不一样

局部变量:没有默认值,如果想要用,必须手动赋值

成员变量:如果没有赋值,会有默认值,规则和数组一样

内存的位置不一样

局部变量:位于栈内存

成员变量:位于堆内存

生命周期不一样

局部变量:随着方法进栈而诞生,随着方法出栈而消失

成员变量:随着对象创建而诞生,随着对象被垃圾回收而消失

标准类的组成部分

一个标准的类通常拥有下面的四个部分:

所有的成员变量都要使用private关键字来修饰

为每一个成员变量编写一对Getter、Setter方法

编写一个无参数的构造方法

编写一个全参数的构造方法

继承

继承是多态的前提,如果没有集成,就没有多态

继承解决的主要问题就是:共性抽取

定义类时的两个注意事项:

成员变量时直接定义在类当中的,在方法外面

成员方法不要写static关键字

继承的格式:

//父类

packagecom.dcits.day08.demo01;

​public classEmployee {public voidmethod() {

System.out.println("父类执行!");

}

}//Teacher子类

packagecom.dcits.day08.demo01

​public class Teacher extendsEmployee{

}//Assistant子类

packagecom.dcits.day08.demo01;

​public class Assistant extendsEmployee {

}//调用

packagecom.dcits.day08.demo01;

​public classDemo01Extends {public static voidmain(String[] args) {

Teacher teacher= newTeacher();

Assistant assistant= newAssistant();

teacher.method();

assistant.method();

}

}

在父子类的继承关系当中,如果成员变量重名,则创建子类时,访问有两种方式:

直接通过子类对象访问成员变量

等号左边是谁,就优先使用谁,没有则向上找

间接通过成员方法访问成员变量

该方法属于谁,就优先用谁,没有则向上找

//父类

packagecom.dcits.day08.demo02;

​public classFu {int numFu = 10;int num = 100;public voidmethodFu() {

System.out.println(num);

}

}

​//子类

packagecom.dcits.day08.demo02;

​public class Zi extendsFu {int numZi = 20;int num = 200;public voidmethodZi() {

System.out.println(num);

}

}

​//调用

packagecom.dcits.day08.demo02;

​public classDemo01ExtendsField {public static voidmain(String[] args) {

Fu fu= newFu();

System.out.println(fu.numFu);

Zi zi= newZi();

System.out.println(zi.numFu);

System.out.println(zi.numZi);

​//当父类与子类的成员变量重名的时候

System.out.println(zi.num);//System.out.println(zi.abc);//zi.methodZi();

zi.methodFu();

}

}

区分子类方法中的三种重名变量

直接使用的方法中的变量

this.变量名:调用本类中的成员变量

super.变量名:调用父类中的成员变量

//父类

packagecom.dcits.day08.demo03;

​public classFu {int num = 10;

}//子类

packagecom.dcits.day08.demo03;

​public class Zi extendsFu {int num = 20;public voidmethod() {int num = 30;

System.out.println(num);//30 局部变量

System.out.println(this.num); //20 本类的成员变量

System.out.println(super.num); //10 父类的成员变量

}

}//调用

packagecom.dcits.day08.demo03;

​public classDemo01ExtendsField {public static voidmain(String[] args) {

Zi zi= newZi();

zi.method();

}

}

继承中成员方法的访问特点

在父子类的继承关系当中,创建子类对象,访问成员方法的规则:创建的对象是谁,就优先使用谁,如果没有则向上找

注意:无论是成员方法还是成员变量,如果没有都是向上找父类u,绝不会向下找子类

//父类

packagecom.dcits.day08.demo04;

​public classFu {

​public voidmethodFu() {

System.out.println("父类中的方法执行啦!");

}

​public voidmethod() {

System.out.println("父类重名执行啦!");

}

}

​//子类

packagecom.dcits.day08.demo04;

​public class Zi extendsFu {public voidmethodZi() {

System.out.println("子类中的方法执行啦!");

}public voidmethod() {

System.out.println("子类重名执行啦!");

}

}

​//调用

packagecom.dcits.day08.demo04;

​public class Zi extendsFu {public voidmethodZi() {

System.out.println("子类中的方法执行啦!");

}public voidmethod() {

System.out.println("子类重名执行啦!");

}

}

继承方法中的覆盖重写

重写:方法的名称一样,参数列表也一样,覆盖、覆写

重载:方法的名称一样,参数列表不一样

方法的覆盖重写特点:创建的是子类对象,则优先用子类方法

方法覆盖重写的注意事项:

必须保证父子类之间的方法名称相同、参数列表也相同

@Override:写在方法前面,用来检测是不是有效的正确覆盖重写,这个注释就算不写,只要满足要求,也是正确的覆盖重写

子类方法的返回值必须小于等于父类方法的返回值范围。Object类是所有类的父类

子类方法的权限必须大于等于父类方法的权限修饰符。public > protected > (default) > private 注意:(default)不是关键字default,而是什么都不写,留空

继承中方法的覆盖重写应用场景

//父类

packagecom.dcits.day08.demo06;//本来的老款手机

public classPhone {public voidcall() {

System.out.println("打电话");

}

​public voidsend() {

System.out.println("发短信");

}

​public voidshow() {

System.out.println("显示号码");

}

}

​//子类

packagecom.dcits.day08.demo06;//上市的新款手机

public class NewPhone extendsPhone {

@Overridepublic voidshow() {//System.out.println("显示号码");

super.show();

System.out.println("显示姓名");

System.out.println("显示头像");

}

}

​//调用

packagecom.dcits.day08.demo06;

​public classDemo01Phone {public static voidmain(String[] args) {

Phone phone= newPhone();

phone.call();

phone.send();

phone.show();

System.out.println("===========");

NewPhone newPhone= newNewPhone();

newPhone.call();

newPhone.send();

newPhone.show();

}

}

继承中构造方法的访问特点

子类构造方法当中有一个默认隐含的 "super()" 调用,所以一定是先调用的父类构造,后执行的子类构造

子类构造可以通过super关键字来调用父类重载构造

super的父类构造调用,只能是第一个语句 ,不能一个子类构造调用多次super构造

子类必须调用父类构造方法,不写赠送super() 写了则用写的指定该的super调用,super只能有一个,还必须是第一个

super关键字的用法(访问父类的内容):

在子类的成员方法中,访问父类的成员变量

在子类的成员方法中,访问父类的成员方法

在子类的构造方法中,访问父类的构造方法

//父类

packagecom.dcits.day08.demo08;

​public classFu {int num = 10;public voidmethod(){

System.out.println("父类方法");

}

}

​//子类

packagecom.dcits.day08.demo08;

​public class Zi extendsFu {int num = 20;publicZi(){super();

}public voidmethodZi() {

System.out.println(super.num); //父类的num

}public voidmethod(){super.method();

System.out.println("子类方法");

}

}

this关键字的三种使用方法(访问本类的内容)

在本类的成员方法中,访问本类的成员变量

在本类的成员方法中访问本类的另一个成员方法

在本类的构造方法中,访问本类的另一个构造方法

注意:

在第三种用法中要注意:this(..)调用必须是构造方法的一个语句,唯一一个

super和this两种构造调用,不能同时使用

//父类

packagecom.dcits.day08.demo09;

​public classFu {int num = 30;

}//子类

packagecom.dcits.day08.demo09;

​public class Zi extendsFu {int num = 20;publicZi(){this(123); //本类的无参构造,调用本类的有参构造//this(1,2)

}public Zi(intn){

}public Zi(int n,intm){

}public voidshowNum(){int num = 10;

System.out.println(num);

System.out.println(this.num); //本类中的成员变量

System.out.println(super.num); //父类中的 成员变量

}public voidmethodA() {

System.out.println("AAA");

}public voidmethodB() {

methodA();this.methodA();

System.out.println("BBB");

}

}

this、super的关键字图解

29c21dfe360bf8e0beeb8e430243bc57.png

Java语言继承的三个特点:

一个类的 直接父类只能有唯一一个

Java语言可以多继承

一个子类的直接父类是唯一的,但是一个父类可以拥有很多个子类

a9f152b49994e45b301490f4d46d2e4f.png

多态

多态的定义以及基本使用

extends继承或者implements实现,是多态的前提。

小明这个对象既有学生形态,也有人类形态。一个对象拥有多种形态,这就是:对象的多态性

9d8851f35a8ea3080323adfb2cafca6f.png

代码当中体现多态性,其实就是一句话:父类引用指向子类对象

格式:

父类名称 对象名 = new 子类名称()

接口名称 对象名 = new 实现类名称()

//父类

packagecom.dcits.day09.demo04;

​public classFu {public voidmethod(){

System.out.println("父类方法");

}public voidmethodFu(){

System.out.println("父类特有方法");

}

}//子类

packagecom.dcits.day09.demo04;

​public class Zi extendsFu {

@Overridepublic voidmethod() {

System.out.println("子类方法");

}

}//调用

packagecom.dcits.day09.demo04;

​public classDemo01Multi {public static voidmain(String[] args) {//使用多态的写法//左侧父类的引用指向右侧子类的对象

Fu obj = newZi();//new 的是谁就调用谁 的方法

obj.method(); //子类方法

obj.methodFu(); //父类特有方法

}

}

多态中成员变量的使用特点

访问成员变量的两种方式:

直接通过对象名称访问成员变量,看等号左边是谁,优先用谁,没有则向上找

间接通过成员方法访问成员变量,看该方法属于谁,优先用谁,没有则像上找

//父类

packagecom.dcits.day09.demo05;

​public classFu {int num = 10;

​public voidshowNum(){

System.out.println(num);

}

}//子类

packagecom.dcits.day09.demo05;

​public class Zi extendsFu {int num = 20;

​int age = 16;

@Overridepublic voidshowNum() {

System.out.println(num);

}

}//调用

packagecom.dcits.day09.demo05;

​public classDemo01MultiField {public static voidmain(String[] args) {

Fu obj= newZi();

System.out.println(obj.num);//父类中的10

System.out.println("=====================");

obj.showNum();//子类没有覆盖重写,就是父类中的num,一旦子类重写后就是子类中的num

}

}

多态中成员方法的使用特点

在多态的代码当中,成员方法的优先访问规则是:看new的是谁,就优先用谁,没有则向上找

注意:编译看左边,运行看右边

对比一下:

成员变量:编译看左边,运行还看左边

成员方法:编译看左边,运行看右边

//父类

packagecom.dcits.day09.demo05;

​public classFu {int num = 10;

​public voidshowNum(){

System.out.println(num);

}

​public voidmethod(){

System.out.println("父类方法");

}public voidmethodFu(){

System.out.println("父类特有方法");

}

}//子类

packagecom.dcits.day09.demo05;

​public class Zi extendsFu {int num = 20;

​int age = 16;

@Overridepublic voidshowNum() {

System.out.println(num);

}

@Overridepublic voidmethod() {

System.out.println("子类方法");

}public voidmethodZi(){

System.out.println("子类特有方法");

}

}

​//调用

packagecom.dcits.day09.demo05;

​public classDemo01MultiField {public static voidmain(String[] args) {

Fu obj= newZi();

obj.method();//父子都有,优先使用子类

obj.methodFu(); //子类没有,父类有,向上找到父类//编译看左,左边是Fu,没有methodZi方法,所以编译报错//obj.methodZi();//错误写法

​//System.out.println(obj.num);//父类中的10//System.out.println("=====================");//obj.showNum();//子类没有覆盖重写,就是父类中的num,一旦子类重写后就是子类中的num

}

}

使用多态的好处

5aa0f94dab3ec61fd33a9e4206efe034.png

对象的向上转型

对象的向上转型,其实就是多态写法

格式: 父类名称 对象名 = new 子类名称()

含义:右侧创建一个子类对象,把它当作父类来看待使用

注意事项:

向上转型一定是安全的,从小范围转到了大范围

但是有一个弊端:对象一旦向上转型为父类,那么就无法调用子类原本的特有内容

类似于:double num = 100 正确 int----double 自动类型转换

3d4d25bdc395a6fdf2fba0b644dc5d5a.png

//父类

packagecom.dcits.day09.demo06;

​public abstract classAnimal {public abstract voideat();

}//子类

packagecom.dcits.day09.demo06;

​public class Cat extendsAnimal {

@Overridepublic voideat() {

System.out.println("猫吃鱼。。。");

}

}

​//调用

packagecom.dcits.day09.demo06;

​public classDemo01Main {public static voidmain(String[] args) {

Animal animal= newCat();

animal.eat();

}

}

对象的向下转型

对象的向下转型,其实是一个还原动作

格式:子类名称 对象名 = (子类名称) 父类对象

含义:将父类对象,还原成为原本的子类对象

注意事项:

必须保证对象本来创建的时候,就是猫,才能向下转型成为猫

如果对象创建的时候本来不是猫,现在非要向下转型成为猫,就会报错

类似于:int num = (int) 10.0 正确 int num = (int) 10.5 错误,发生精度损失

//父类

packagecom.dcits.day09.demo06;

​public abstract classAnimal {public abstract voideat();

}//猫子类

packagecom.dcits.day09.demo06;

​public class Cat extendsAnimal {

@Overridepublic voideat() {

System.out.println("猫吃鱼。。。");

}

​public voidcatchMouse() {

System.out.println("猫抓老鼠!!");

}

}

​//狗子类

packagecom.dcits.day09.demo06;

​public class Dog extendsAnimal {

@Overridepublic voideat() {

System.out.println("狗吃shit");

}

​public voidwatchMouse() {

System.out.println("狗看家!!");

}

}

​//调用

packagecom.dcits.day09.demo06;

​public classDemo01Main {public static voidmain(String[] args) {

Animal animal= new Cat(); //对象的向上转型

animal.eat();

​//向下转型

Cat cat =(Cat) animal;

cat.catchMouse();//猫抓老鼠!!

​//下面是错误的向下转型//本来new的时候是一只猫,现在非要转成狗//java.lang.ClassCastException

Dog dog = (Dog) animal; //错误写法

}

}

f3182f2f844542a1173d0954aa6dbd3b.png

用instanceof 关键字进行类型判断

packagecom.dcits.day09.demo06;

​public classDemo01Instanceof {public static voidmain(String[] args) {

Animal animal= new Cat(); //本来是一只猫

animal.eat();

​//如果需要调用子类特有的方法,需要向下转型

if (animal instanceofDog){

Dog dog=(Dog) animal;

dog.watchMouse();

}if (animal instanceofCat){

Cat cat=(Cat) animal;

cat.catchMouse();

}

giveMeAPet(new Dog()); //在你调用这个方法的时候,方法本身不知道传递过来的是哪个类,所以需要进行判断

}

​public static voidgiveMeAPet(Animal animal){if (animal instanceofDog){

Dog dog=(Dog) animal;

dog.watchMouse();

}if (animal instanceofCat){

Cat cat=(Cat) animal;

cat.catchMouse();

}

}

}

接口多态的综合案例

//USB接口类:两个抽象方法:打开USB、关闭USB

packagecom.dcits.day09.demo07;

​public interfaceUSB {

​public abstract voidopen();

​public abstract voidclose();

}

​//电脑类:开机、关机、连接USB接口并对USB设备进行对应操作

packagecom.dcits.day09.demo07;

​public classComputer {public voidpowerOn(){

System.out.println("笔记本电脑开机");

}

​public voidpowerOff(){

System.out.println("笔记本电脑关机");

}

​//使用USB设备的方法,使用接口作为方法的参数

public voiduseDevice(USB usb) {

usb.open();//判断当前类是属于哪个类之后,在获取类中的特有方法

if (usb instanceofMouse){

Mouse mouse=(Mouse) usb;

mouse.click();

}else if (usb instanceofKeyBoard){

KeyBoard keyboard=(KeyBoard) usb;

keyboard.type();

}

usb.close();

}

}

​//鼠标类:重写接口类中的打开、关闭功能,并实现自己的独有功能

packagecom.dcits.day09.demo07;

​public class Mouse implementsUSB {

@Overridepublic voidopen() {

System.out.println("打开鼠标");

}

@Overridepublic voidclose() {

System.out.println("关闭鼠标");

}

​public voidclick(){

System.out.println("点击鼠标!");

}

}

​//键盘类:重写接口类中的打开、关闭功能,并实现自己的独有功能

packagecom.dcits.day09.demo07;

​public class KeyBoard implementsUSB {

@Overridepublic voidopen() {

System.out.println("打开键盘");

}

@Overridepublic voidclose() {

System.out.println("关闭键盘");

}

​public voidtype(){

System.out.println("敲键盘!");

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值