面向对象9天

编程入门 行业动态 更新时间:2024-10-24 14:16:18

<a href=https://www.elefans.com/category/jswz/34/1769334.html style=面向对象9天"/>

面向对象9天

面向对象9天

一、面向对象编程day01

1.类和对象

  • 类是用来创建对象的模板,对象是类的具体实例,它包含被创建对象的属性和方法。
  • 对象的属性/特征------成员变量(实例变量)
  • 对象的行为/动作------实例方法
  • 对象:真实存在的单个个体/东西,基于对象抽出了类
package ooday09;
/**
*成员变量(实例变量)
*/
public class Apple {String color;//定义颜色成员变量String address;//定义产地成员变量double price;//定义价格成员变量
}

2.方法

封装的是具体的业务逻辑实现。

  • 方法的声明
  • 方法体
package ooday09;
/**
* 成员变量和成员方法的结合使用
*/
public class Count {public int add(int src, int des){//带参数和返回值的成员方法int num = src + des;return num;}public static void main(String[] args) {Count count = new Count();//创建对象int apple1 = 30;//局部变量int apple2 = 20;//局部变量int num = count.add(apple1,apple2);//调用成员方法System.out.println("苹果的总数为:"+ num);//50}
}
public class Student { //Student类就是我们自己造的一种引用类型//成员变量String name;int age;String address;//方法void study(){System.out.println(name+"在学习...");}void sayHi(){System.out.println("大家好,我叫"+name+",今年"+age+"岁了,家住"+address);}
}public class StudentTest {public static void main(String[] args){//创建一个学生对象Student zs = new Student();//给成员变量赋值zs.name = "zhangsan";zs.age = 25;zs.address = "河北廊坊";//调用方法zs.study();zs.sayHi();Student ls = new Student();ls.name = "lisi";ls.age = 24;ls.address = "黑龙江佳木斯";ls.study();ls.sayHi();//1)创建了一个学生对象//2)给所有成员变量赋默认值Student ww = new Student();ww.study();ww.sayHi();}
}

3.方法的重载

  • 发生在同一类中,方法名相同,参数列表不同
  • 编译器在编译时会根据方法的签名自动绑定方法
class(){void show(){}void show(int age){//方法名相同,参数列表不同}int show(){//编译错误,与返回值类型无关}void show(int num){//编译错误,与参数名称无关}
}
//重载的演示
public class OverloadDemo {public static void main(String[] args) {Aoo o = new Aoo();o.show(); //编译器根据方法的签名自动绑定方法o.show("zhangsan");o.show(25);o.show("zhangsan",25);o.show(25,"zhangsan");}
}class Aoo{void show(){}void show(String name){}void show(int age){}void show(String name,int age){}void show(int age,String name){}//int show(){ return 1;} //编译错误,重载与返回值类型无关//void show(String address){} //编译错误,重载与参数名称无关
}

补充:

  • 引用基本类型创建对象

student zs (指向) = new student();

数据类型 引用类型变量 对象(new 出来的叫对象)

若要访问对象,需要通过引用,可参考上面Count例子

  • 默认值规则
    • byte,short,int,long,char-------0
    • float,double--------------------------0.0
    • boolean-------------------------------false

二、面向对象编程day02

1.构造方法

  • 用于对对象中的成员变量赋初值即初始化。

  • 构造方法是一种特殊的方法,他的名字必须和他所在类的名字完全相同,并且没有返回值(连void也没有)。

  • 创建对象是被自动调用

  • 若自己不写构造方法,则编译器默认提供一个无参构造方法,若自己写了构造方法,则不再默认提供

  • 构造方法可以重载

package ooday09;
/**
* 定义Apple类,在该类的构造方法中初始化成员变量
*/
public class Apple {int num;float price;Apple apple;public Apple(){//默认的构造方法num = 10;price = 8.34f;System.out.println("默认无参构造方法");}public static void main(String[] args) {Apple apple = new Apple();//创建对象System.out.println("苹果的数量:"+apple.num);System.out.println("苹果的单价:"+ apple.price);}
}

2. this

  • 指代当前对象,哪个对象调用方法它指的就是哪个对象, 只能用在方法中,方法中访问成员变量之前默认有个this。
  • this的用法
    • this.成员变量名-------------访问成员变量
    • this.方法名()-----------------调用方法(了解)
    • this()---------------------------调用构造方法(了解)

成员变量与局部变量同名时,若想访问成员变量则this不能省略

class Student {String name; //成员变量(整个类中)int age;String address;//局部变量(当前方法中)Student(String name,int age,String address){this.name = name;this.age = age;this.address = address;}void study(){System.out.println(name+"在学习...");}void sayHi(){                       System.out.println("大家好,我叫"+name+",今年"+age+"岁了,家住"+address);}}

3. null

student zs = null;//引用类型变量可以赋值为null,null表示空,没有指向任何对象,int a = null;错误,基本类型与null无关
/*null 表示空,没有指向任何对象,若引用的值为null,则该引用不能进行任何点操作了,若操作则发生 NullPointerException 空指针异常。*/
  • 内存图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mpSsPoy0-1644044614645)(E:\达内\图片\null和NullPointerException.png)]

4.引用类型数组

  • 步骤

    1.创建引用类型数组

    2.通过new 对象给元素赋值

    3.若想访问对象的数据,需要通过数组元素去打点

Bomb[] bs = new Bomb[3];
bs[0] = new Bomb(100,200); //1)给元素赋值需要去new个对象
bs[1] = new Bomb(200,300);
bs[2] = new Bomb(220,330);
//2)若想访问对象的数据,需要通过数组元素去打点
bs[0].x = 111; //给第1个炸弹的x修改为111  
System.out.println(bs[1].width); //输出第2个炸弹的宽
bs[2].move(); //第3个炸弹移动
  • 内存图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T8c5iF0c-1644044614647)(E:\达内\图片\引用类型与基本类型内存图.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UNdUDRXp-1644044614648)(E:\达内\图片\引用类型与基本类型内存图.png)]

补充:

  1. 成员变量:写在类中,方法外--------有默认值

    局部变量:方法中------------------------没有默认值

  2. java规定:成员变量和局部变量是可以同名的

    • 使用的时候默认采取的是就近原则
  3. 内存管理:由JVM来管理的

    • 堆:new出来的对象(包括成员变量)
    • 栈:局部变量(包括方法的参数)
    • 方法区:-----------见day04
  4. 数组也是一个对象,所以数组对象也存储在堆中,

    将数组的元素当作成员变量一并存储在堆中

三、面向对象编程day03

1.引用数组遍历

Student student = new Student[3];//创建引用数组对象
student[0] = new Student(10);
student[1] = new Student(20);
student[2] = new Student(30);
System.out.println(student[0].age);//输出第一个学生的年龄
for(int i = 0;i<student[i].length;i++){
System.out.println(student[i].age)
}

2.继承

  • 作用---------代码复用。在面向对象程序设计中,继承是不可或缺的一部分。

    (1)特点:

  • 通过extends来实现继承

  • 超类/父类:共有的属性和行为

  • 派生类/子类:特有的属性和行为

  • 派生类既能访问自己的,也能访问超类的,但超类不能访问派生类的

  • 一个超类可以有多个派生类

  • 一个派生类只能有一个超类-----------单一继承

  • 具有传递性

  • java规定:构造派生类之前必须先构造超类

    • 派生类的构造方法中若没有调用超类的构造方法,则默认super()调用超类的无参构造方法
    • 派生类的构造方法中若自己调用了超类的构造方法,则不再默认提供

(2)使用原则

  • 子类能够继承父类中被声明public和protected的成员变量和成员方法,但不能继承父类中被声明为private的成员变量和成员方法。
  • 子类能够继承在同一个包中由默认修饰符修饰的成员变量和成员方法。
  • 如果子类声明了一个与父类的成员变量同名的成员变量,则子类不能继承父类的成员变量,此时称子类的成员变量隐藏了父类的成员变量。
  • 如果子类声明了一个与父类的成员方法同名的成员方法,则子类不能继承父类的成员方法,此时称子类的成员方法隐藏了父类的成员方法即重写。
package ooday09;/*** 创建一个名为Animal的类,在该类中声明一个成员变量live和两个成员方法,分别为eat()和move()*/
public class Animal {public boolean live = true;public String skin = "";public void eat(){System.out.println("动物需要吃食物");}public void move(){System.out.println("动物会移动");}}package ooday09;/*** 创建Animal类的一个子类Bird,在该类中隐藏(重写)了父类的成员变量skin,并且覆盖了成员方法move()*/
public class Bird extends Animal{public String skin = "羽毛";public void move(){System.out.println("鸟会飞翔");}}package ooday09;/*** 创建一个名为Zoo的类,在该类的main()方法中创建子类Bird的对象并为该对象分配内存,然后* 对象调用该类的成员方法及成员变量*/
public class Zoo {public static void main(String[] args) {Bird bird = new Bird();bird.eat();bird.move();System.out.println("鸟有,"+bird.skin);/*动物需要吃食物鸟会飞翔鸟有,羽毛*/}
}

3. super:

指代当前对象的超类对象。

用法:

  1. super.成员变量名----访问父类(超类)的成员变量

  2. super.方法名()------调用超类的方法,一般用在方法的重写上

  3. super()------------调用超类的构造方法

super调用超类构造方法,必须位于派生类构造方法第一行

class Aoo{Aoo(){System.out.println("超类无参构造");}
}
class Boo extends Aoo{Boo(){super();//默认调用超类的无参构造System.out.println("子类无参构造");}public static void main(String[] args){Boo o = new Boo();/*超类无参构造子类(派生类)无参构造*/}
}
  • java 规定:构造派生类之前必须先构造超类;
  • 派生类的构造方法中若没有调用超类的构造方法,则默认super()调用超类的无参构造方法;
  • 派生类的构造方法中若自己调用了超类的构造方法,则不再默认提供。

4.向上造型-----代码复用

一个对象可以看作本类类型,也可以看作它的超类类型。取得一个对象的引用并将它看作超类的对象,成为向上转型。

  • 超类型的引用指向了派生类的对象
  • 能点出什么,看引用的类型----- java 的规定
Zoo o = new Zoo();
Parrot parrot = new Parrot();
Zoo o = new Parrot();//向上造型
例子:
package ooday09;/*** */
abstract  class Animal1{public abstract void move();//抽象方法见day05,移动方法
}
class Parrot extends  Animal1{@Overridepublic void move(){//鹦鹉移动方法System.out.println("鹦鹉正在飞行。。。。。。");}
}class Tortoise extends Animal1{@Overridepublic void move(){//乌龟移动方法System.out.println("乌龟正在爬行。。。。。。");}
}public class Zoo {public void free(Animal1 animal1){animal1.move();}public static void main(String[] args) {Zoo zoo = new Zoo();Parrot parrot = new Parrot();Tortoise tortoise = new Tortoise();zoo.free(parrot);//鹦鹉正在飞行。。。。。。zoo.free(tortoise);//乌龟正在爬行。。。。。。}
}

补充

  1. 继承意味着代码虽然我没有写,但也属于我,只是没有写在一起而已
  2. 泛化:将共有的抽出来的过程,泛化是设计层面的概念,从代码实现层面来说咱们就是继承,泛化就是继承
  3. 继承要符合is a(是一个)的关系

四、面向对象编程 day04

1.方法的重写

  • 发生在父子类中,方法名相同,参数列表相同

  • 重写方法被调用时,看对象的类型------------这是规定,记住就OK

    当派生类觉得超类的行为不够好时,可以重写

我继承了一个中餐馆
class Aoo{void do(){做中餐}
}
A:我还是想做中餐------------不需要重写class Boo extends Aoo{}
B:我想改做西餐--------------需要重写class Boo extends Aoo{void do(){做西餐}}
C:我想在中餐基础之上加西餐-----需要重写(先super中餐,再加入西餐)class Boo extends Aoo{void do(){super.do();做西餐}}

重写与重载的区别:-----------面试题

重写:发生在父子类中,方法名相同,参数列表相同,一般用于在派生类中修改超类的方法

**重载:**发生在同一类中,方法名相同,参数列表不同,是完全不同的方法,只是方法名相同而已

2. package 和 import

  • package声明包
    • 作用:避免类的命名冲突
    • 同包中的类不能同名,不同包中的类可以同名
    • 类的全称:包名.类名。
    • 包名常常有层次结构,包名全都小写
Package a;//必须位于第一行
class Aoo{}
a.Aoo//类的全称
  • import:导入类
    • 同包中的类可以直接访问,不同包的类不能直接访问,若想访问:
      • 先import导入类,再访问类----------建议
      • 类的全称-----------------------------------太繁琐,不建议

说明:import导入类必须位于声明包的下一行

Package a;//必须位于第一行
import java.util.Scanner;//包名下面第一行,先import导入类,再访问类
class Aoo{Scanner sc = new Scanner();java.util.Scanner sc = new java.util.Scanner(System.in)//为导包,用类全称,不建议
}
a.Aoo//类的全称

3.访问控制修饰符-------常见面试题

  • public:公开的,任何类
  • private:私有的,本类
  • protected:受保护的,本类、派生类、同包类
  • 默认的:什么也不写,本类、同包类
  1. 类的访问权限只能是public或默认的
  1. 类中成员的访问权限如上四种都可以
//访问权限范围:
package ooday04;
//演示访问控制修饰符
public class Aoo {public int a;     //任何类protected int b;  //本类、派生类、同包类int c;            //本类、同包类private int d;    //本类void show(){a = 1;b = 2;c = 3;d = 4;}
}class Boo{ //---------------演示privatevoid show(){Aoo o = new Aoo();o.a = 1;o.b = 2;o.c = 3;//o.d = 4; //编译错误}
}package ooday04_vis;
import ooday04.Aoo;
public class Coo { //演示同包的概念void show(){Aoo o = new Aoo();o.a = 1;//o.b = 2; //编译错误//o.c = 3; //编译错误//o.d = 4; //编译错误}
}class Doo extends Aoo{ //演示protectedvoid show(){a = 1;b = 2;//c = 3; //编译错误//d = 4; //编译错误}
}

4. static

在一个class中定义的字段,我们称之为实例字段。实例字段的特点是,每个实例都有独立的字段,各个实例的同名字段互不影响。 还有一种字段,是用static修饰的字段,称为静态字段:static field。

实例字段在每个实例中都有自己的一个独立“空间”,但是静态字段只有一个共享“空间”,所有实例都会共享该字段。举个例子:

class Person {public String name;public int age;// 定义静态字段number:public static int number;
}

(1)静态变量

  • 由static修饰
  • 属于类,存储在方法区中,只有一份
  • 常常通过类名点来访问
  • 何时用:所有对象所共享的数据(图片、音频、视频等)
public class StaticDemo {public static void main(String[] args) {Eoo o1 = new Eoo();o1.show();Eoo o2 = new Eoo();o2.show();Eoo o3 = new Eoo();o3.show();System.out.println(Eoo.b); //常常通过类名点来访问}
}class Eoo{ //演示静态变量int a;static int b;Eoo(){a++;b++;}void show(){System.out.println("a="+a+",b="+b);}
}a=1,b=1
a=1,b=2
a=1,b=2

​ 虽然实例可以访问静态字段,但是它们指向的其实都是Eoo

class的静态字段。所以,所有实例共享一个静态字段。 因此,不推荐

用实例变量.静态字段去访问静态字段,因为在Java程序中,实例对象

并没有静态字段。在代码中,实例对象能访问静态字段只是因为编译

器可以根据实例类型自动转换为类名.静态字段来访问静态对象。

(2)静态方法:

  • 由static修饰
  • 属于类,存储在方法区中,只有一份
  • 常常通过类名点来访问
  • 静态方法没有隐式this传递,所以不能直接访问实例成员
  • 何时用:方法的操作与对象无关
//static的演示
public class StaticDemo {public static void main(String[] args) {Goo.plus(4,6);}
}//演示静态方法
class Foo{int a; //实例变量(由对象来访问)static int b; //静态变量(由类名来访问)void show(){ //有隐式thisSystem.out.println(this.a);System.out.println(Foo.b);}static void test(){//静态方法中没有隐式this传递//没有this就意味着没有对象//而实例变量a是必须由对象来访问的//所以下面的语句发生编译错误//System.out.println(a); //编译错误System.out.println(Eoo.b);}
}//演示静态方法何时用
class Goo{int a; //对象的属性//方法中用到了对象的属性a,意味着show()的操作与对象是有关的,不能做成静态方法void show(){System.out.println(a);}//方法中没有用到对象的属性和行为,意味着plus()的操作与对象是无关的,可以做成静态方法static void plus(int num1,int num2){int num = num1+num2;System.out.println(num);}
}

静态变量与实例变量的区别:

  • 静态变量:由static修饰,属于类,存储在方法区,只有一份,通过类名打点访问。
  • 实例变量:没有static修饰,属于对象,存储在堆中,有几个对象就有就有几份,通过引用打点访问

(3)静态块

  • 由static修饰
  • 属于类,在类被加载期间自动执行,一个类只加载一次,所以静态块也执行一次
public class StaticDemo {public static void main(String[] args) {Hoo o4 = new Hoo();Hoo o5 = new Hoo();Hoo o6 = new Hoo();}
}
//演示静态块
class Hoo{static {System.out.println("静态块");}Hoo(){System.out.println("构造方法");}
}/*
静态块
构造方法
构造方法
*/
  • 在构造方法中给实例变量赋初值
  • 在静态块中给静态变量赋初值

5.重写的规则

两同两小一大原则

**两同:**方法名相同,参数列表相同

**两小:**派生类方法的返回值类型必须小于或等于超类方法

  • void和基本类型时,必须相等
  • 引用类型时小于或等于

派生类方法抛出的异常必须小于或等于超类方法的-------见API

**一大:**派生类方法的访问权限必须大于或等于超类的返回权限

class Aoo{public   void show(){}
}
class Boo extends Aoo{void show(){//错误,访问权限要大于超类的}
}
权限自身同包子类不同包子类同包类其他类
private访问
默认访问继承访问
protected访问继承继承访问
public访问继承继承访问访问

五、面向对象编程 day05

1. final:最终的,不可改变的

  • 修饰变量:变量不能改变
  • 修饰方法:方法不能被重写
  • 修饰类:类不能不继承
  • 修饰引用:引用被修饰成final,表示该引用只有一次指向对象的机会
/**
*	使用final修饰变量
*/
class Aoo{final int num = 5;void show(){//num = 55;//编译错误,final的变量不能被改变}
}
/**
*	使用final修饰方法
*/
class Boo{final void show(){}
}
class Coo extends Boo{//void show(){}//编译错误,final修饰的方法不能被重写
}
/**
*	final修饰类不能被继承
*/
final class Doo{}
//class Eoo extends Doo{}//编译错误,final的类不能被继承
class Foo{}
final class Goo extends Foo{}//不能当老爸,但可以当儿子

2. static final常量:应用率高

  • 必须声明同时初始化
  • 通过类名点来访问,不能被改变
  • 建议:常量名所有字母都大写,多个单词用_分隔
  • 编译器在编译时会将常量直接替换为具体的值,效率高
  • 何时用:数据永远不变,并且经常使用
public class StaticFinalDemo{public static void main(String[] args){System.out.println(Hoo.PI);//通过类名点来访问//Hoo.PI = 3.1415926;//编译错误,常量不能被改变/*1.加载Ioo.class到方法去2.将静态变量num一并存储到方法区中3.到方法区中获取num的值并输出*/System.out.priintln(Ioo.num);/*编译器在编译时将常量替换为具体的值,效率高相当于System.out.println(5);*/System.out.println(Ioo.COUNT);}
}class Ioo{public static int num = 5;//静态变量public static final int COUNT = 5;//常量
}
class Hoo{public static final double PI = 3.14159;//public static final int NUM;//编译错误。常量必须声明的同时并初始化
}

3.抽象方法

  • 由abstract修饰
  • 只有方法的定义,没有具体的实现(连{}都没有)

4. 抽象类

  • 由abstract修饰

  • 包含抽象方法的类必须是抽象类

  • 抽象类不能被实例化(new对象)

  • 抽象类是需要被继承的,派生类:

    • 重写所有抽象方法--------------变不完整为完整
    • 也声明为抽象类------------------一般不这么做
  • 由abstract修饰

  • 包含抽象方法的类必须是抽象类

  • 抽象类不能被实例化(new对象)

  • 抽象类是需要被继承的,派生类:

    • 重写所有抽象方法--------------变不完整为完整
    • 也声明为抽象类------------------一般不这么做
  • 抽象类的意义:

    • 封装共有的属性和行为--------------------代码复用

    • 为所有派生类提供统一的类型-----------向上造型—代码复用

    • 可以包含抽象方法,为所有派生类提供统一的入口(能点出来)

      派生类的行为不同,但入口是一致的,同时相当于定义了一个标准

    • 修饰类:类不能被继承
  1. static final常量:应用率高

    • 必须声明同时初始化
    • 通过类名点来访问,不能被改变
    • 建议:常量名所有字母都大写,多个单词用_分隔
    • 编译器在编译时会将常量直接替换为具体的值,效率高
    • 何时用:数据永远不变,并且经常使用
  2. 抽象方法:

    • 由abstract修饰
    • 只有方法的定义,没有具体的实现(连{}都没有)
  3. 抽象类:

    • 由abstract修饰

    • 包含抽象方法的类必须是抽象类

      不包含抽象方法的类也可以声明为抽象类-------------了解

    • 抽象类不能被实例化(new对象)

    • 抽象类是需要被继承的,派生类:

      • 重写所有抽象方法--------------变不完整为完整
      • 也声明为抽象类------------------一般不这么做
    • 抽象类的意义:

      • 封装共有的属性和行为--------------------代码复用

      • 为所有派生类提供统一的类型-----------向上造型—代码复用

      • 可以包含抽象方法,为所有派生类提供统一的入口(能点出来)

        派生类的行为不同,但入口是一致的,同时相当于定义了一个标准

:**

  1. 设计规则:

    • 将派生类所共有的属性和行为,抽到超类中-------------抽共性

    • 派生类的行为都一样,则设计为普通方法

      派生类的行为不一样,则设计为抽象方法

    • ------------下周二讲

  2. 抽象方法/抽象类的疑问:

    • 抽象方法的存在意义是什么?

      • 保证当发生向上造型时,通过超类型的引用能点出来那个方法
    • 既然意义只在于能点出来,那为什么不设计为普通方法?

      • 若设计为普通方法,则派生类可以重写也可以不重写,而设计为抽象方法,可以强制派生类必须重写------做了个标准,强制必须重写

六、面向对象编程day06

1.成员内部类

  • 类中套类,外面的成为外部类,里面的称为内部类
  • 内部类通常只服务于外部类,对外不具备可见性
  • 内部类对象只能在外部类中创建
  • 内部类中可以直接访问外部类的成员(包括私有的),在内部类中有个隐式的引用指向了创建它的外部对象--------外部类名.this
public class InnerClassDemo{public static void main(String[] args){Mama m = new Mama();//Baby b =  new Baby();//编译错误,内部类对外不具备可见性}
}class Mama{//外部类private String name;Baby b = new Baby();//内部类对象通常在外部类中创建class Baby{//内部类void show(){System.out.println(name);System.out.println(Mama.this.name);//Mama.this指代它的外部类对象}}}

2. 匿名内部类

  • 应用率高---------大大简化代码
  • 若想创建一个类(派生类)的对象,并且对象只创建一个,此时该类不必命名,称为匿名内部类
  • 匿名内部类中不能修改外面变量的值,因为在此处该变量默认为final的
public class AnonInnerClassDemo{public static void main(String[] args){/*1.创建Aoo的一个派生类,但是没有名字2.为该派生类创建一个对象,名为o13.大括号中的为派生类的类体*/Aoo o1 = new Aoo(){};/*1.创建了Aoo的一个派生类。但是没有名字2.为该派生类创建一个对象,名为o2;3.大括号中的为派生类的类体*/Aoo o2 = new Aoo(){};int num = 5;num = 55;/*1.创建了Boo的一个派生类,但是没有名字2.为该派生类创建一个对象,名为o33.大括号中的为派生类的类体*/Boo o3 = new Boo(){void show(){System.out.println("showshow");//num = 66;//编译错误,匿名内部类不能修饰外面变量的值,因为在此处默认为final的}};o3.show();}
}abstract class BOO{abstract void show();
}
abstract class Aoo{}

补充:

  1. 隐式对象:

    • this:当前对象
    • super:当前对象的超类对象
    • 外部类名.this:当前对象的外部类对象
  2. 必须记住的,API中会用的:

    • 外部类名.this:指代当前对象的外部类对象
    • 匿名内部类不能修改外面变量的值,因为在此处默认为final的
  3. 小面试题:

    • 问:内部类有独立的.class字节码文件吗?

      答:有

  4. 做功能的套路:

    • 先写行为/方法:
      • 若为某对象所特有的行为,就将方法设计在特定的类中
      • 若为所有对象所共有的行为,就将方法设计在超类中
    • 窗口调用:
      • 若为定时发生的,就在定时器中调用
      • 若为事件触发的,就在侦听器中调用----------明天上午讲
  5. 调错方式:

    • 打桩:System.out.println(数据);

七、面向对象编程day07

1.接口

  • 是一种引用数据类型
  • 有interface定义
  • 只能包含常量和抽象方法-----默认权限是public
  • 接口不能被实例化
  • 接口是需要实现/继承,实现/派生类:必须重写所有的抽象方法
  • 一个类可以实现多个接口,用逗号分隔,若又继承又实现时,应先继承后再实现
  • 接口可以继承接口
  • 接口的意义:
    • 封装部分派生类共有的属性和行为,实现多继承
    • 指定一个标准,一种规范
public class InterfaceDemo{public static void main(String[] args){Inter o = new Inter();//编译错误,接口不能被实例化Inter5 o1 = new Doo();//向上造型Inter4 o2 = new Doo();//向上造型}
}//演示接口的定义
interface Inner{public static final int NUM = 5;//接口中的成员默认访问权限是publicvoid COUNT = 5;//默认public static finalvoid test();//默认public abstract//int number;//编译错误,常量必须声明同时初始化//void say(){}//编译错误,抽象方法不能有方法体}
//演示接口的定义
interface Inner1{void show();void test();
}
class Aoo implements Inter1{public void show(){}//重写接口中的抽象方法是,访问权限必须设计为public的public void test(){}
}
//演示接口的多实现
interface Inter2{void show();
}
interface Inter3{void test();
}
abstract class Boo{abstract void say();
}
class Coo extends Boo implements Inter2.Inter3{public void show(){}public void test(){}void say(){}
}//演示接口继承接口
interface Inter4{void show();
}
interface Inter5 extends Inter4{void test();
}
class Doo implements Inter5{public void test(){}public void show(){}
}

补充:

  1. 类和类------------------------继承extends

    接口和接口------------------继承extends

    类和接口---------------------实现implements

  2. 设计规则:

    • 将所有派生类所共有的属性和行为,抽到超类中-------------抽共性

    • 派生类的行为都一样,则设计为普通方法

      派生类的行为不一样,则设计为抽象方法

    • 将部分派生类所共有的属性和行为,抽到接口中

      接口是对继承的单根性的扩展---------------实现多继承

      符合既是也是原则时,应使用接口

  3. 可以向上造型为:超类+所实现的接口

八、面向对象编程day08

1.多态

  • 表现:

    • 同一个对象被造型为不同的类型时,有不同的功能

      –对象的多态:我、你、水…------所有对象都是多态的(明天体会)

    • 同一类型的引用指向不同的对象时,有不同的实现

      –行为的多态:cut(),move(),getImage()–所有抽象方法都是多态的

  • 向上造型/自动类型转换:--------------------代码复用

    • 超类型的引用指向派生类的对象
    • 能点出来什么,看引用的类型
    • 能造型成为的数据类型有:超类+所实现的接口
  • 强制类型转换,成功的条件只有如下两种:

    • 引用所指向的对象,就是该类型
    • 引用所指向的对象,实现了该接口或继承了该类
  • 强转时若不符合如上条件,则发生ClassCastException类型转换异常

    建议:在强转之前先通过instanceof来判断引用的对象是否是该类型

public class MultiTypeDemo{public static void main(String[] args){Aoo o = new Boo();Boo o1 = o;//引用o所指向的对象,就是Boo类型Inter o2 = (Inter)o//引用o所指向的对象,实现了Inter接口//Coo o3 = (Coo)o;//运行时classcastException类型转换异常if(o instanceof Coo){//falseCoo o4 = (Coo)o;}else{System.out.println("o不是Coo类型");}}
}interface Inter{}
class Aoo{}
class Boo extends Aoo implements Inter{}
class Coo extends Aoo{}

补充:

  1. 接口可以继承多个接口:

    interface Inter1{void show();
    }
    interface Inter2{void test();
    }
    interface Inter3 extends Inter1,Inter2{void say();
    } 
    
  2. 何时需要强转?

    • 想访问的属性/行为在超类中没有,必须强转,强转之前先instanceof判断
  3. ArrayIndexOutOfBoundsException:数组下标越界异常

    NullPointerException:空指针异常

    ClassCastException:类型转换异常

九、面向对象编程day09

1.内存管理:由JVM管理的

堆:

  • 存储new出来的对象(包括实例变量)

  • 垃圾:没有任何引用所指向的对象

    垃圾回收器(GC)不定时到内存堆中清扫垃圾,回收的过程中透明的(看不到的),不一定一发现垃圾就立刻回收,通过调用System.gc()建议虚拟机尽快调度GC来回收

  • 实例变量的生命周期:

    ​ 创建对象时存储在堆中,对象被回收时一并被回收

  • 内存泄漏:不再使用的对象没有被及时的回收,严重的泄漏会导致系统的崩溃,建议:不再使用的对象应及时将引用设置为null

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-22qKIfU3-1644044614649)(E:\达内\图片\堆-1.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jzt4quul-1644044614649)(E:\达内\图片\堆-2.png)]

栈:

  • 存储正在调用的方法中的局部变量(包括方法的参数)

  • 调用方法时,会为该方法在栈中分配一块对应的栈帧,栈帧中存储局部变量(包括方法的参数),方法调用结束时,栈帧被自动清除,局部变量一并被清除。

  • 局部变量的生命周期:

    ​ 调用方法时存储在栈中,方法调用结束时与栈帧一并被清除

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IuWln0AF-1644044614649)(E:\达内\图片\栈.png)]

方法区:

  • 存储.class字节码文件(包括静态变量、所有方法)
  • 方法只有一份,通过this来区分具体的调用对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-py5msOyd-1644044614650)(E:\达内\图片\方法区.png)]

面向对象三大特征总结:

1.封装

  • 类:封装对象的属性和行为
  • 方法:封装的是具体的业务逻辑实现
  • 访问控制修饰符:封装的是具体的访问权限(public protected private 默认)

2. 继承

  • 作用:代码复用
  • 超类:所有派生类所共有的属性和行为
  • 接口:部分派生类所共有的属性和行为
  • 派生/实现类:派生类所特有的属性和行为
  • 单一继承,多接口实现,具有传递性

3.多态

  • 行为多态:所有的抽象方法都是多态的(通过重写来表现)

    对象多态:所有对象都是多态的(通过向上造型为表现)

  • 重写、向上造型、强制类型转换、instanceof判断

应知应会:------面试题

  1. Java的8种基本数据类型是什么

    8种基本数据类型包括:byte,short,int,long,float,double,boolean,char

    • byte:字节型,用于存储整数的,占用1个字节,范围-128到127
    • short:短整型,用于存储整数的,占用2个字节,范围-32768到32767
    • int:最常用的整型,用于存储整数的,占用4个字节,范围-231到231-1
    • long:长整型,用于存储较大的整数的,占用8个字节,范围-263到263-1
    • float:单精度浮点型,用于存储小数的,占用4个字节,不能表示精确的值
    • double:双精度浮点型,最常用的存储小数的类型,占用8个字节,不能表示精确的值
    • boolean:布尔型,存储true或false,占用1个字节
    • char:字符型,采用Unicode字符编码格式,存储单个字符,占用2个字节
  2. 方法重载与重写的区别

    • 方法的重载(overload):发生在同一类中,方法名相同,参数列表不同
    • 方法的重写(override):发生在父子类中,方法名相同,参数列表相同
  3. Java是值传递还是引用传递

    java中无论是基本类型还是引用类型,都是值传递:

    • 对于基本类型而言,传递的是具体的值的副本----------是在赋值
    • 对于引用类型而言,传递的是具体的地址值的副本----是在指向同一个对象
  4. switch能作用在哪些类型的变量上

    • switch可以作用于:byte,short,int,char,String,枚举类型上,其余类型是不允许的
  5. 实例变量和静态变量的区别

    实例变量和静态变量都属于成员变量

    • 实例变量:是属于对象的,在创建对象的时候存储在内存堆中,创建多少个对象,则实例变量就会在内存中存在多少份,需要通过引用名打点来进行访问
      mg-IuWln0AF-1644044614649)]

方法区:

  • 存储.class字节码文件(包括静态变量、所有方法)
  • 方法只有一份,通过this来区分具体的调用对象

[外链图片转存中…(img-py5msOyd-1644044614650)]

面向对象三大特征总结:

1.封装

  • 类:封装对象的属性和行为
  • 方法:封装的是具体的业务逻辑实现
  • 访问控制修饰符:封装的是具体的访问权限(public protected private 默认)

2. 继承

  • 作用:代码复用
  • 超类:所有派生类所共有的属性和行为
  • 接口:部分派生类所共有的属性和行为
  • 派生/实现类:派生类所特有的属性和行为
  • 单一继承,多接口实现,具有传递性

3.多态

  • 行为多态:所有的抽象方法都是多态的(通过重写来表现)

    对象多态:所有对象都是多态的(通过向上造型为表现)

  • 重写、向上造型、强制类型转换、instanceof判断

应知应会:------面试题

  1. Java的8种基本数据类型是什么

    8种基本数据类型包括:byte,short,int,long,float,double,boolean,char

    • byte:字节型,用于存储整数的,占用1个字节,范围-128到127
    • short:短整型,用于存储整数的,占用2个字节,范围-32768到32767
    • int:最常用的整型,用于存储整数的,占用4个字节,范围-231到231-1
    • long:长整型,用于存储较大的整数的,占用8个字节,范围-263到263-1
    • float:单精度浮点型,用于存储小数的,占用4个字节,不能表示精确的值
    • double:双精度浮点型,最常用的存储小数的类型,占用8个字节,不能表示精确的值
    • boolean:布尔型,存储true或false,占用1个字节
    • char:字符型,采用Unicode字符编码格式,存储单个字符,占用2个字节
  2. 方法重载与重写的区别

    • 方法的重载(overload):发生在同一类中,方法名相同,参数列表不同
    • 方法的重写(override):发生在父子类中,方法名相同,参数列表相同
  3. Java是值传递还是引用传递

    java中无论是基本类型还是引用类型,都是值传递:

    • 对于基本类型而言,传递的是具体的值的副本----------是在赋值
    • 对于引用类型而言,传递的是具体的地址值的副本----是在指向同一个对象
  4. switch能作用在哪些类型的变量上

    • switch可以作用于:byte,short,int,char,String,枚举类型上,其余类型是不允许的
  5. 实例变量和静态变量的区别

    实例变量和静态变量都属于成员变量

    • 实例变量:是属于对象的,在创建对象的时候存储在内存堆中,创建多少个对象,则实例变量就会在内存中存在多少份,需要通过引用名打点来进行访问
    • 静态变量:是属于类的,在类被加载时存储在内存方法区中,无论创建多少个对象,静态变量在内存中都只存在一份,常常通过类名点来访问。

更多推荐

面向对象9天

本文发布于:2024-03-09 01:11:18,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1723179.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:面向对象

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!