java基础--面向对象4
来源:互联网 发布:sql 设置列默认值 编辑:程序博客网 时间:2024/06/05 12:31
1.字段不存在多态
上节讲了继承和多态,那字段是否也存在多态呢:
class Super {public String name = "super.class";public void doWork() {System.out.println("super.dowork");}}class SubClass extends Super {public String name = "sub.class";public void doWork() {System.out.println("sub.dowork");}}public class FieldDemo {public static void main(String[] args) {Super clz = new SubClass();clz.doWork();//sub.doworkSystem.out.println(clz.name);//super.class}}
通过对象调用字段,在编译时期就已经觉得了调用哪一个块内存空间的数据,
----------------------->字段不存在覆盖的概念,在多态时候,不能有多态特征(在运行时期体现子类特征)
当子类和父类存在相同的字段时候,无论修饰符是什么.即使是private,都会在各自的空间中存储数据.
什么是代码块:
在类或者方法中,直接使用”{}”括起来的一段代码,表示一块代码区域
代码块里变量属于局部变量,只是在自己所在区域(前后的{})有效.
根据代码块定义的位置不同,我们分为三种形式:
(1)局部代码块:直接定义在方法内部的代码块:
//代码块class CodeBlockDemo{public static void main(String[] args) {System.out.println("Hello world!");{//局部代码块int age = 17;System.out.println(age);}}}
一般我们不会直接使用局部代码块的,会结合if,while,where等关键字联合,表示一块代码区域
(2)初始化代码块(构造代码块):直接定义在类中
每次创建对象的是时候都会执行初始化代码
每次创建对象都会调用构造器,但是在调用构造器之前,会先执行本类中的初始化代码块
(3)静态代码块:使用static修饰的初始代码块
在主方法之前执行静态代码块,且只执行一次
Main方法是程序的入口,为什么静态代码块优先于main方法
--->静态成员随着字节码的加载而加载到jvm,此时main方法还未执行,因为方法需要jvm调用
先把字节码加载到jvm,而后jvm在调用main方法
我们一般用来作初始化操作,加载资源
为什么要是用final修饰符:
继承关系最大的弊端是破坏封装,子类能访问父类的实现细节,而且可以通过方法覆盖的形式修改实现细节
------------------------------------------------------------
多个修饰符直接是没有先后关系的. public static final / public static final
--------------------------------------------------------------------------------------------------
final本身的含义是 “最终的不可改变的”,它可以修饰非抽象类,非抽象方法和变量.
注意:构造方法不能够使用final修饰,因为构造方法不能被继承,肯定是最终的.
Final修饰的类:最终的类,不能再有子类
fianl class SuperClass{}class SubClass extends SuperClass//FinalDemo.java:5:错误:无法从最终SuperClass进行继承{}
满足以下条件就可以把一个类设计成final类:
(1)某类不是专门为继承而设计的
(2)出于安全考虑,类的实现细节不允许改的,不准修改源代码
(3)明确该类不会被再拓展
列举java中内置所用final修饰的类
Java内用final修饰的类有很多,例如八大基本数据类型保证类和string类
------------------------------------------------------------------------------------------------------------
Final修饰的方法:最终的方法,该方法不能被子类覆盖.
什么时候的方法需要使用final修饰.
(1)在父类中提供的统一的算法骨架,不准子类通过方法覆盖来修改时候,此时使用final修饰,模板方法设计模式
(2)构造器中调用的方法(初始化方法),初始化方法一般使用final修饰
Final修饰的方法,子类可以调用,但是不能覆盖
class SuperClass{final public void doWork(){}}class SubClass extends SuperClass{public void doWork();//错误:SubClass 的doWork()无法覆盖SuperClass中的doWork(){}}
-----------------------------------------------------------------------------------------------------------------
Final修饰的变量:表示常量,只能赋值一次,不能再赋值
(1)Final变量必须显式的指定初始值,系统不会给final字段初始化
(2)Final变量一点赋予初始值,就不能被重复赋值
class FinalDemo {final static String name = null;public static void main(String[] args) {name = "bb";//错误:无法为最终变量name分配值System.out.println(name);}}
(3)常量名规范: 常量名符号标识符,单词全部大写,单词键使用下划线隔开
Int 类型的最大值: final int MAX_VALUE = ...;
补充:全局静态常量 public static final 修饰的变量,直接使用类名调用即可.
------------------------------------------------------------------------------------------------------------------
面试题:final修饰的引用类型变量到底表示引用的地址不能改变,还是引用的空间中的数据不能改变
Final修饰的基本类型变量:表示变量的值不能改变,不能用”=”号重复赋值
Final修饰的引用类型变量:表示该变量的引用地址不能变,而不是引用地址里的内容不能变
------------------------------------------------------------------------------------------------------------------
Final是唯一可以修饰局部变量的修饰符.------------------局部内部类
什么时候使用常量:
当在程序中,多个地方使用到共同的数据,而且该数据不会被改变,此时我们专门定义全局的常量.
一般放到一个常量类中
class Contact {public static final int X_SIZE = 100;public static final int Y_SIZE = 100;}
-----------------------------------------------------------------------------------------------------------------
设计模式(Design pattern):是一套反复使用,多人知晓的,进过分类编目地,代码设计经验的总结.
使用设计模式是为了重用代码,让代码更容易被他人理解,保证代码可靠性.毫无疑问,设计模式于人于己都是多赢的
------------------------------------------------------------------------------------------------------------------
单例设计模式(singleton):
目的:保证某一个在整个应用中有且只有一个实例(一个类在内存只存在一个对象),即所有指向该类型实例的引用都指向同一块内存空间
需求:定义一个数组的工具类,使用单例设计模式解决
写单例模式的步骤:单讲饿汉式
(1)必须在该类中,自己先创建一个对象.
(2)私有化自身的构造器,防止外界通过构造器创建新的对象
(3)向外暴露一个公共的静态方法,用于获取自身的对象
class ArrayUtil {//(1)必须在该类中,自己先创建一个对象private static final ArrayUtil instance = new ArrayUtil();//(2)私有化自身构造器,防止外界通过构造器创建新对象private ArrayUtil() {}//(3)向外暴露一个公共的静态方法,用于获取自身的对象public static ArrayUtil getInstance() {return instance;}public void sort(int[] arr) {System.out.println("排序操作");}}
//单例设计模式class SingletonDemo {public static void main(String[] args) {//需要做排序操作ArrayUtil.getInstance().sort(null);}}
-----------------------------------------------------------------------------------------------------------------
工具类:存放了某一类事物的工具方法的类.
工具类存放的包:工具包(util/utils,tools/tool,)存放工具类
工具类起名: xxxUtil/xxxTools
例如: ArrayUtil,StringUtil
工具类如何设计:工具类在开发中只需要存在一份
(1)如果工具方法没有使用static修饰,说明工具方法得使用工具类的对象来调用
此时把工具类设计为单例的
(2)如果工具方法全部使用static修饰,工具方法只需要使用工具类名调用即可
此时必须把工具类的构造器私有化(防止创建工具类对象调用静态方法)
----------------------------------
一般首选第二种,简单,在jdk中提供的工具类都是第二种如java.util.Arrays类
引出基本类型的包装类
问题1:在面向对象中,”一切皆对象”,现在问题:给一个整数常量int age = 17 ;请问这里age哪里有对象?基本类型,不是对象,此时有矛盾.
问题2 :现在给一个复杂的十进制数据,请迅速转为2进制8 进制, 16进制
问题3:现在使用一种数据类型来表示考试成绩,怎么表示缺考核考试的0分
------------------------------------------------------------------------------------------------------------
上述问题,就是因为基本数据类型缺少对象.如果需要对象,必须先有类.
此时我们可以为每一个基本类型都编写一个对应的包装类,类中包含了该基本类型的一个值.
装箱及拆箱
八大基本数据类型的包装类都是用final修饰,都是最终类,都不能被继承.
在java的集合框架中,只能存储对象,不能存储基本类型的值.
每次存储到集合中的基本数据都得手动来装箱
Sun从java5开始,提供自动装箱和拆箱
自动装箱和拆箱,也是一个语法糖/编译器级别的新特性
在底层依然是手动装箱和拆箱操作
但是:装箱操作使用的是integer.valueOf的方式
-----------------------------------------------------------------------------------------------------------------
Switch 支持的数据类型:byte,short,char,int也支持对应的包装类
在底层Switch会对包装类做手动拆箱操作
解释 Object obj = 17;
(1)先有一个自动装箱操作 int i = 17;
(2)引用类型的自动转换,把子类对象赋给父类对象Object obj = i;
------------------------------------------------------------------------------------------------------------------
Object可以接受一切数据类型的值
包装类的常用操作方法
1.包装类的常量:
MAX_VALUE/MIN_VALUE/SIZE(在内存中存储多少位)/TYPE(对应的类型)
2.包装类的构造器,xxx类型的包装类xxx
构造器作用:创建包装类
3.基本类型和包装类型的转换(装箱和拆箱)
装箱:
Integer i1 = new Integer(123);
Integer i2 = integer.valueOf(123);//推荐方式,带有缓存
拆箱:
Int a = I1.intValue();
xxxValue:表示把当前对象转换为xxx类型
Byte byteValue();
Short shortValue();
4.String和基本类型/包装类型之间的转换操作
将String类型转换为包装类
方法1:Static xxx valueOf(String str) 把string转换为包装类对象
Int i1 = integer.ValueOf(“123”);
方法2: new xxx(String str):
Int i2 = new integer(“123”);
将基本数据类型转为String类型
String str = 17 + “”;
将包装类型转为String类型
String str = 任何对象.toString()
将String转为基本数据类型:
parseXxx(String x) : xxx表示八大基本数据类型
String input = “12345”;
Int a = Integer .parseInt(input);
包装类的缓存设计,享元模式flyweight 一种软件设计模式:
Byte short,integer,long:缓存[-128.127]之间的数据;
Character:缓存[0,127]之间的数据
class CacheDemo {public static void main(String[] args) {Integer i1 = new Integer(123);Integer i2 = new Integer(123);System.out.println(i1 == i2);//falseInteger i3 = Integer.valueOf(123);Integer i4 = Integer.valueOf(123);System.out.println(i3 == i4);//true:在[-1218,127]之间,就获取缓存中的数据Integer i5 = 123;Integer i6 = 123;System.out.println(i5 == i6);//trueInteger i11 = new Integer(255);Integer i21 = new Integer(255);System.out.println(i11 == i21);//falseInteger i31 = Integer.valueOf(255);Integer i41 = Integer.valueOf(255);System.out.println(i31 == i41);//false:不在[-1218,127]之间,就重新new一个Integer i51 = 255;Integer i61 = 255;System.out.println(i51 == i61);//true}}
包装类型对象之间的比较操作:统统使用equals来比较,比较的是包装的数据(Integer类中将equals重写)
特别指出利用equals比较八大包装对象
(如int,float等)和String类(因为该类已重写了equals和hashcode方法)对象时,默认比较的是值,在比较其它自定义对象时都是比较的引用地址。
Integer和int的区别
(1)默认值:
Int类型是0
Integer默认值为Null
(2)包装类中提供了该类型的很多算法操作方法
Static String toBinaryString(int i): 十进制转换为二进制
Static String toOctalString
(3)在集合框架中,只能存储对象类型,不能存储基本数据类型
(4)Integer 和int不是相同的数据类型
上述设计的问题:
(1)每个图像都有面积,所有在graph类中定义的求面积方法getArea没问题但是不同的具体求面积的算法是不一样的,也就是说每个图像的子类都必须去覆getAREA方法,如果不覆盖,应该语法报错,必须覆盖
(2)在图像类中定义了getArea方法,该方法不应该存在方法体,因为不同的图像求面积算法不一样,父类不知道该怎么写,所以应该提供方法体方法.
-----------------------------------------------------------------------------------------------------------
抽象方法
使用abstract修饰的且没有方法体的方法,称为抽象方法
特点:
(1)使用abstract修饰的且没有方法体的方法
(2)抽象方法修饰符不能是private和fianl和static
(3)抽象方法需要放在抽象类或者接口中
抽象类
abstract修饰的类
特点:
(1)不能创建实例即不能new一个抽象类,即使创建抽象类方法,调用抽象方法没有方法体
(2)可以不包含抽象方法,若一旦包含,该类必须作为抽象类,抽象类可以包含普通方法
(3)若子类没有实现/覆盖父类所有的抽象方法,那么子类也得作为抽象类
(4)构造方法不能都定义为私有的,否则不能有子类(创建子类之前先调用父类的构造方法)
(5)是不完整的,需要作为父类(必须要有子类),功能才得以实现
--------------------------------------------------------------------------------------
抽象类不能实例化
抽象类中可以不存在抽象方法,但是没有太大的意义
--------------------------------------------------------------------------------------
抽象类和普通类的区别
普通类有的常用(方法,字段,构造器),抽象类都有
抽象类不能创建对象,抽象类中可以包含抽象方法
模板方法设计模式:在父类的方法中定义一个总体算法骨架(模板方法),而将一些不足延迟到子类中,因为不同的子类实现细节不同.模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤
---------------------------------------------------------------------------------------------------------
抽象父类赋值定义操作中的业务骨架,而把某些具体的实现步骤延迟到子类中去实现
抽象父类至少提供的方法:
(1)模板方法:一种统一的处理方式,即模板
(2)抽象方法:一种具体的业务功能实现,有子类完成
注意抽象父类提供的模板方法只是定义了一个通用算法,其实现不想依赖子类的辅助
- java基础 面向对象4
- Java基础--面向对象4
- java基础--面向对象4
- java基础 面向对象
- Java面向对象基础
- java基础-面向对象
- java面向对象基础
- JAVA面向对象基础
- Java面向对象基础
- Java面向对象基础
- java基础----面向对象
- java 面向对象基础
- 【Java基础】面向对象
- java基础面向对象
- JAVA面向对象基础
- Java基础:面向对象
- java基础---面向对象
- Java基础--面向对象
- SprintBoot学习笔记(4):登录(Hibernate+Mysql)
- JVM内幕:Java虚拟机详解
- 如何看待那些不能重现的bug
- [BZOJ]1923: [Sdoi2010]外星千足虫 高斯消元解xor方程组
- bzoj 1222: [HNOI2001]产品加工
- java基础--面向对象4
- Redis 数据库迁移
- HTTP和https区别
- idea常用快捷键
- C++PRIMER第六章练习
- json
- 微软研发-致胜策略品读心得
- Tomcat是什么。Tomcat入门介绍
- LINUX中常用操作命令