类是用来创建对象的模板,对象是类的具体实例,它包含被创建对象的属性和方法。对象的属性/特征------成员变量(实例变量)对象的行为/动作------实例方法对象:真实存在的单个个体/东西,基于对象抽出了类
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-------0float,double--------------------------0.0boolean-------------------------------false 二、面向对象编程day02 1.构造方法
用于对对象中的成员变量赋初值即初始化。
构造方法是一种特殊的方法,他的名字必须和他所在类的名字完全相同,并且没有返回值(连void也没有)。
创建对象是被自动调用
若自己不写构造方法,则编译器默认提供一个无参构造方法,若自己写了构造方法,则不再默认提供
构造方法可以重载
package ooday09;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()---------------------------调用构造方法(了解)
3、null成员变量与局部变量同名时,若想访问成员变量则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); } }
student zs = null;//引用类型变量可以赋值为null,null表示空,没有指向任何对象,int a = null;错误,基本类型与null无关
内存图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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)]
补充:
成员变量:写在类中,方法外--------有默认值
局部变量:方法中------------------------没有默认值
java规定:成员变量和局部变量是可以同名的
使用的时候默认采取的是就近原则
内存管理:由JVM来管理的
堆:new出来的对象(包括成员变量)栈:局部变量(包括方法的参数)方法区:-----------见day04
数组也是一个对象,所以数组对象也存储在堆中,
将数组的元素当作成员变量一并存储在堆中
三、面向对象编程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
作用---------代码复用。在面向对象程序设计中,继承是不可或缺的一部分。
(1)特点:
通过extends来实现继承
超类/父类:共有的属性和行为
派生类/子类:特有的属性和行为
派生类既能访问自己的,也能访问超类的,但超类不能访问派生类的
一个超类可以有多个派生类
一个派生类只能有一个超类-----------单一继承
具有传递性
java规定:构造派生类之前必须先构造超类
派生类的构造方法中若没有调用超类的构造方法,则默认super()调用超类的无参构造方法派生类的构造方法中若自己调用了超类的构造方法,则不再默认提供
(2)使用原则
子类能够继承父类中被声明public和protected的成员变量和成员方法,但不能继承父类中被声明为private的成员变量和成员方法。子类能够继承在同一个包中由默认修饰符修饰的成员变量和成员方法。如果子类声明了一个与父类的成员变量同名的成员变量,则子类不能继承父类的成员变量,此时称子类的成员变量隐藏了父类的成员变量。如果子类声明了一个与父类的成员方法同名的成员方法,则子类不能继承父类的成员方法,此时称子类的成员方法隐藏了父类的成员方法即重写。
package ooday09;public class Animal { public boolean live = true; public String skin = ""; public void eat(){ System.out.println("动物需要吃食物"); } public void move(){ System.out.println("动物会移动"); }}package ooday09;public class Bird extends Animal{ public String skin = "羽毛"; public void move(){ System.out.println("鸟会飞翔"); }}package ooday09;public class Zoo { public static void main(String[] args) { Bird bird = new Bird(); bird.eat(); bird.move(); System.out.println("鸟有,"+bird.skin); }}
3、super:指代当前对象的超类对象。
用法:
super.成员变量名----访问父类(超类)的成员变量
super.方法名()------调用超类的方法,一般用在方法的重写上
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{ @Override public void move(){//鹦鹉移动方法 System.out.println("鹦鹉正在飞行。。。。。。"); }}class Tortoise extends Animal1{ @Override public 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);//乌龟正在爬行。。。。。。 }}
补充:
继承意味着代码虽然我没有写,但也属于我,只是没有写在一起而已泛化:将共有的抽出来的过程,泛化是设计层面的概念,从代码实现层面来说咱们就是继承,泛化就是继承继承要符合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 和 importpackage声明包
作用:避免类的命名冲突同包中的类不能同名,不同包中的类可以同名类的全称:包名.类名。包名常常有层次结构,包名全都小写
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:受保护的,本类、派生类、同包类默认的:什么也不写,本类、同包类
类的访问权限只能是public或默认的 类中成员的访问权限如上四种都可以
//访问权限范围: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{ //---------------演示private void 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{ //演示protected void 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=1a=1,b=2a=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(){ //有隐式this System.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(){//错误,访问权限要大于超类的 }}
修饰变量:变量不能改变修饰方法:方法不能被重写修饰类:类不能不继承修饰引用:引用被修饰成final,表示该引用只有一次指向对象的机会
class Aoo{ final int num = 5; void show(){ //num = 55;//编译错误,final的变量不能被改变 }}
class Boo{ final void show(){}}class Coo extends Boo{ //void show(){}//编译错误,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;//编译错误,常量不能被改变 System.out.priintln(Ioo.num); 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对象)
抽象类是需要被继承的,派生类:
重写所有抽象方法--------------变不完整为完整也声明为抽象类------------------一般不这么做
抽象类的意义:
封装共有的属性和行为--------------------代码复用
为所有派生类提供统一的类型-----------向上造型—代码复用
可以包含抽象方法,为所有派生类提供统一的入口(能点出来)
派生类的行为不同,但入口是一致的,同时相当于定义了一个标准
修饰类:类不能被继承
static final常量:应用率高
必须声明同时初始化通过类名点来访问,不能被改变建议:常量名所有字母都大写,多个单词用_分隔编译器在编译时会将常量直接替换为具体的值,效率高何时用:数据永远不变,并且经常使用
抽象方法:
由abstract修饰只有方法的定义,没有具体的实现(连{}都没有)
抽象类:
由abstract修饰
包含抽象方法的类必须是抽象类
不包含抽象方法的类也可以声明为抽象类-------------了解
抽象类不能被实例化(new对象)
抽象类是需要被继承的,派生类:
重写所有抽象方法--------------变不完整为完整也声明为抽象类------------------一般不这么做
抽象类的意义:
封装共有的属性和行为--------------------代码复用
为所有派生类提供统一的类型-----------向上造型—代码复用
可以包含抽象方法,为所有派生类提供统一的入口(能点出来)
派生类的行为不同,但入口是一致的,同时相当于定义了一个标准
补充:**
设计规则:
将派生类所共有的属性和行为,抽到超类中-------------抽共性
派生类的行为都一样,则设计为普通方法
派生类的行为不一样,则设计为抽象方法
------------下周二讲
抽象方法/抽象类的疑问:
抽象方法的存在意义是什么?
保证当发生向上造型时,通过超类型的引用能点出来那个方法
既然意义只在于能点出来,那为什么不设计为普通方法?
若设计为普通方法,则派生类可以重写也可以不重写,而设计为抽象方法,可以强制派生类必须重写------做了个标准,强制必须重写 六、面向对象编程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){ Aoo o1 = new Aoo(){ }; Aoo o2 = new Aoo(){ }; int num = 5; num = 55; Boo o3 = new Boo(){ void show(){ System.out.println("showshow"); //num = 66;//编译错误,匿名内部类不能修饰外面变量的值,因为在此处默认为final的 } }; o3.show(); }}abstract class BOO{ abstract void show();}abstract class Aoo{ }
补充:
隐式对象:
this:当前对象super:当前对象的超类对象外部类名.this:当前对象的外部类对象
必须记住的,API中会用的:
外部类名.this:指代当前对象的外部类对象匿名内部类不能修改外面变量的值,因为在此处默认为final的
小面试题:
问:内部类有独立的.class字节码文件吗?
答:有
做功能的套路:
先写行为/方法:
若为某对象所特有的行为,就将方法设计在特定的类中若为所有对象所共有的行为,就将方法设计在超类中 窗口调用:
若为定时发生的,就在定时器中调用若为事件触发的,就在侦听器中调用----------明天上午讲
调错方式:
打桩: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;//接口中的成员默认访问权限是public void COUNT = 5;//默认public static final void 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(){}}
补充:类和类------------------------继承extends
接口和接口------------------继承extends
类和接口---------------------实现implements
设计规则:
将所有派生类所共有的属性和行为,抽到超类中-------------抽共性
派生类的行为都一样,则设计为普通方法
派生类的行为不一样,则设计为抽象方法
将部分派生类所共有的属性和行为,抽到接口中
接口是对继承的单根性的扩展---------------实现多继承
符合既是也是原则时,应使用接口
可以向上造型为:超类+所实现的接口
八、面向对象编程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){//false Coo o4 = (Coo)o; }else{ System.out.println("o不是Coo类型"); } }}interface Inter{}class Aoo{}class Boo extends Aoo implements Inter{}class Coo extends Aoo{}
补充:接口可以继承多个接口:
interface Inter1{ void show();}interface Inter2{ void test();}interface Inter3 extends Inter1,Inter2{ void say();}
何时需要强转?
想访问的属性/行为在超类中没有,必须强转,强转之前先instanceof判断
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判断
应知应会:------面试题Java的8种基本数据类型是什么
8种基本数据类型包括:byte,short,int,long,float,double,boolean,char
byte:字节型,用于存储整数的,占用1个字节,范围-128到127short:短整型,用于存储整数的,占用2个字节,范围-32768到32767int:最常用的整型,用于存储整数的,占用4个字节,范围-231到231-1long:长整型,用于存储较大的整数的,占用8个字节,范围-263到263-1float:单精度浮点型,用于存储小数的,占用4个字节,不能表示精确的值double:双精度浮点型,最常用的存储小数的类型,占用8个字节,不能表示精确的值boolean:布尔型,存储true或false,占用1个字节char:字符型,采用Unicode字符编码格式,存储单个字符,占用2个字节
方法重载与重写的区别
方法的重载(overload):发生在同一类中,方法名相同,参数列表不同方法的重写(override):发生在父子类中,方法名相同,参数列表相同
Java是值传递还是引用传递
java中无论是基本类型还是引用类型,都是值传递:
对于基本类型而言,传递的是具体的值的副本----------是在赋值对于引用类型而言,传递的是具体的地址值的副本----是在指向同一个对象
switch能作用在哪些类型的变量上
switch可以作用于:byte,short,int,char,String,枚举类型上,其余类型是不允许的
实例变量和静态变量的区别
实例变量和静态变量都属于成员变量
实例变量:是属于对象的,在创建对象的时候存储在内存堆中,创建多少个对象,则实例变量就会在内存中存在多少份,需要通过引用名打点来进行访问
mg-IuWln0AF-1644044614649)]
方法区:
存储.class字节码文件(包括静态变量、所有方法)方法只有一份,通过this来区分具体的调用对象
[外链图片转存中…(img-py5msOyd-1644044614650)]
面向对象三大特征总结: 1.封装类:封装对象的属性和行为方法:封装的是具体的业务逻辑实现访问控制修饰符:封装的是具体的访问权限(public protected private 默认) 2、继承
作用:代码复用超类:所有派生类所共有的属性和行为接口:部分派生类所共有的属性和行为派生/实现类:派生类所特有的属性和行为单一继承,多接口实现,具有传递性 3.多态
行为多态:所有的抽象方法都是多态的(通过重写来表现)
对象多态:所有对象都是多态的(通过向上造型为表现)
重写、向上造型、强制类型转换、instanceof判断
应知应会:------面试题Java的8种基本数据类型是什么
8种基本数据类型包括:byte,short,int,long,float,double,boolean,char
byte:字节型,用于存储整数的,占用1个字节,范围-128到127short:短整型,用于存储整数的,占用2个字节,范围-32768到32767int:最常用的整型,用于存储整数的,占用4个字节,范围-231到231-1long:长整型,用于存储较大的整数的,占用8个字节,范围-263到263-1float:单精度浮点型,用于存储小数的,占用4个字节,不能表示精确的值double:双精度浮点型,最常用的存储小数的类型,占用8个字节,不能表示精确的值boolean:布尔型,存储true或false,占用1个字节char:字符型,采用Unicode字符编码格式,存储单个字符,占用2个字节
方法重载与重写的区别
方法的重载(overload):发生在同一类中,方法名相同,参数列表不同方法的重写(override):发生在父子类中,方法名相同,参数列表相同
Java是值传递还是引用传递
java中无论是基本类型还是引用类型,都是值传递:
对于基本类型而言,传递的是具体的值的副本----------是在赋值对于引用类型而言,传递的是具体的地址值的副本----是在指向同一个对象
switch能作用在哪些类型的变量上
switch可以作用于:byte,short,int,char,String,枚举类型上,其余类型是不允许的
实例变量和静态变量的区别
实例变量和静态变量都属于成员变量
实例变量:是属于对象的,在创建对象的时候存储在内存堆中,创建多少个对象,则实例变量就会在内存中存在多少份,需要通过引用名打点来进行访问静态变量:是属于类的,在类被加载时存储在内存方法区中,无论创建多少个对象,静态变量在内存中都只存在一份,常常通过类名点来访问。