Java第七章 类和对象

可将将类看做是对象的载体

1.对象:静态部分,动态部分,静态的为属性,动态的为行为。

面向对象的三大特点:

1.封装:封装变化,让封装的类或组件,尽量只负责一个领域的工作.。

2.继承:主要利用对象的共性解决同样的问题,概念形成统一,通过继承可以管理多个概念。

3.多态:同一个行为的不同表现方法 ,解决父类的方法在子类不适合的问题。

主要思想:

分而治之,高内聚,低耦合,封装变化。

主要原则:

开-闭原则:对扩展开放,对修改关闭。

类的单一指责:类定义的时候,只包含一个或者一类与类本身关系的密切功能。一个类有且只有一个改变它的原因。

面向接口编程而非面向实现:先思考做什么,为其他的组件提供什么功能。

优先使用组合而非继承:如果仅仅为了复用类,优先选择组合,如果需要复用代码的同时服用概念,使用继承。组合的耦合性比继承低。

依赖倒置:尽量依赖抽象,因为抽象是稳定的,实现是多变的。

里氏替换:子类在重写父类方法时,尽量选择扩展重写。

接口隔离:尽量定义小而精的接口,少定义大而全的接口。

迪米特法则:类与类交互时,在满足功能的基础上,传递的数据约少越好,这样可以降低耦合度。

1.构造方法:与类 同名的方法,创建类的对象时自动调用,在类中没有定义任何构造方法时,编译器会在该类中提供一个不带参数的构造方法,当类中有自定义的构造方法,则不提供,如果定义的是有参构造方法,那么调用无参构造方法会报错。这里跟C#是一样的,如果在类中定义了有参的构造函数,那么必须再定义一个无参的构造函数,否则调用无参构造函数会报错。this关键字可以调用类的成员变量和方法。这里还要注意下接口和抽象方法。

c#语法:构造方法不会继承给子类,但是在创建子类对象时,先从子进入父,自动调用父类的构造方法,且父类构造方法先执行,子类构造方法后执行.当子类采用无参构造方法创建对象时,默认调用父类的无参构造方法,如果父类没有无参构造方法,则报编译错误(如果父类给了有参的构造函数,就不会给无参的构造函数,这时用子类的无参创建对象就会报错),解决方法有两个: 1.为父类添加无参构造方法, 2.在子类的构造方法中用base关键字指明要调用父类的哪一个有参构造方法,2优先1.多态的方式有:重写,隐藏,重载,抽象方法,接口。

隐藏方法:本质指的是方法用new修饰的方法,如果使用隐藏技术,调用父中的方法有2中 父类对象= new 父类()父类对象= new 子类()。如果使用隐藏技术,调用子类的方法有1中。子类 对象= new 子类()缺点:不能实现父调子!原理:两个地址,new谁在谁的方法列表中找,声明谁找谁的方法地址。

虚方法重写:用vritual关键修饰的已经实现的方法,子类中的方法名字前加 override,也可以不重写。与隐藏方法不同的是父类对象= new 子类()调子类。原理:重写方法表中地址。方法列表中有2个方法。但是原方法的地址被新方法的地址覆盖,所以new父类调用子类的方法,

抽象方法:抽象方法用abstract修饰,在子类中必须重写,除非子类中也是抽象的。重写方法用关键字override,已经重写过的方法,在子类还可以继续重写,除非被标识为sealed。sealed修饰的为封闭方法或者类。不能够被继承。封闭类(sealed修饰的类)的特点,可以new ,不能被继承。抽象类(abstract修饰的类)不能实例化,可以被继承。抽象类中可以有字段,可以有实现方法。抽象方法没有实现。抽象方法只能出现在抽象类中。放在抽象类中的抽象方法必须加abstract,实现类在实现抽象类中的抽象方法必须加Override。放在接口中的抽象方法不能加abstract,实现类在实现接口中的抽象方法不加Override。

定义使用关键字interface创建的数据类型。

接口:接口名建议用”I”开头,其后单词首字母大写。接口只关注行为,不关注数据(不能有字段),且不关注行为的实现(没有方法体),实现由实现类完成。接口是定义一组对外的行为规范,要求它的实现类必须遵循(行为默认是Public并且不能添加public,实现类必须实现接口中所有成员)父债子还也就是说子类中实现所有方法,可以有自动属性,在子类中实现。实现类中必须加public(除显示实现:方法名改为接口名加”。并且不能加任何访问修饰符,默认为private,显式实现成员只能通过接口类型的引用调用)。接口中的所有成员不能加任何访问修饰符,全部默认公有。接口中的所有成员不能有实现,全部默认抽象的。解决接口中的成员对实现类不适用的问题  如果接口中包含的方法比较多,个别不适合实现类,不适合的用显示实现,好处就是通过类的引用无法调用,【一定程度上的避免了接口污染】,解决多接口实现时的二义性。结构(struct)可以实现接口,但不能继承类

静态绑定:是指调用关系是在运行之前确定的,即编译期间 方法隐藏是静态绑定

动态绑定:是指调用关系是在运行期间确定的。运行期间,方法重写是动态绑定(运行时改地址)

-------------------------------------------------------

java语法:接口用interface关键字, 接口名以I为开头,extends 关键字用来指定继承哪个父接口。接口里可以有字段 ,但是必须初始化  接口里的字段必须为公开的、静态的、终态的(final关键字修饰也就是说是静态的),但是方法可以是私有的(Java9新特性之一)。public 等权限修饰符可以有也可以没有,没有则默认为默认权限,protected。接口只能继承接口,类只能继承类。implements 关键字用来指定该类实现了那些接口,用逗号分割多个。接口后面不能用关键字implements。一个类只能继承一个类,但是可以实现多个接口(注意这里类只能继承类不能继承接口),接口可以多继承接口并且不能继承类。这里继承时有个“@Override”,它是伪代码,表示重写(当然不写也可以),不过写上有如下好处:  1、可以当注释用,方便阅读; 2、编译器可以给你验证@Override下面的方法名是否是你父类中所有的,如果没有则报错。而如果你不加@Override,则编译器将不会检测出错误,而是会认为你为子类定义了一个新方法。类不能实现类。是能实现接口。接口继承多个和接口时用“,”隔开。类实现多个接口时也用“,”隔开.继承和实现同时需要时,先写继承 再写实现 用空格 分开即可。

继承:类继承抽象类时,声明父类  new 子类 调用子类方法 , 声明子类  new 子类 调用子类方法, 抽象类不能实例化。java里的super关键字代替C#里的base关键字。

多态:方法的重写Overloading和重写Overriding, 这里有一个实现泛型comparable<T>接口的案例可以看一下。

抽象类:用abstract关键字修饰,抽象方法不能用private或static关键字修饰。静态类的已经实现的方法和字段可以为私有的。有抽象方法的类必须是抽象类,

内部类:在一个类中再定义一个类,后者称为内部类,分为,成员内部类、局部内部类、匿名内部类。内部类中可以随意使用外部类的成员方法以及成员变量(private的也可以),这里内部类一定要绑在外部类上,也就是说在外部类初始化一个内部类对象,那么内部类就会绑定在外部类上,外部类只能使用内部类的非私有的成员,并且需要内部类的对象调用。若果想再外部类外面创建内部类的对象,需要先创建外部类对象 再创建 格式如下 外部类 对象 = new 外部类(), 外部类。内部类 对象名= 对象.new 内部类(),这也说明了内部类对象依赖外部类对象。如果有内部类和外部类的成名名称相同的情况,那么内部类中的为默认为内部类的成员,用this关键字点修饰的也是内部类成员,但是用外部类。this。修饰的为外部成员。局部内部类: 就是在类的方法中定义的内部类,它的作用范围是在这个方法内,在方法的外部不能访问该内部类,但是内部类可以访问外部类的所有成员。匿名内部类:由于匿名内部类没有名称,所以匿名内部类用默认的构造方法来生成匿名内部类的对象,在匿名内部类定以后需要加分号标识。并代表创建匿名内部类的引用表达式的标识,并会生成外部类$序号未名称的.class文件。匿名内部类的使用条件是必须继承一个类或者实现一个接口,实质就是省略了定义子类并创建子类对象再调用父类成员的过程。简化了代码。格式:接口 对象 = new 接口(){...};这里接口和抽象类正常是不能new对象的。静态内部类:在内部类前加static就为内部静态类。静态内部类中可以声明static成员,担非静态内部类中不可以声明静态成员,静态内部类不能使用外部类的非静态成员。创建静态内部类的对象不需要外部类的对象, 格式 外部类.内部类 对象 = new 类.内部类();内部类的继承:内部类可以和其他普通类一样被继承,但是继承内部类比继承普通类要复杂,需要设置专门的语法,继承时用关键字 extends  ClassA(外部类)。ClassB(内部类),在子类中必须硬性的给这个类一个有参的构造函数(calassA a),并且参数为需要继承的内部类的外部类的引用,同时在构造函数中使用a。super()这样才为继承提供了必要的对象引用。并且内部类不能为静态内部类。

2.静态:虽然可以用对象也可以点出静态成员, 但是建议使用类名点出静态成员,否则容易造成混淆。静态方法中不可以使用关键字this,也不可以直接调用非静态方法。在方法体内的局部变量声明为静态的也是错误的。protected修饰的类或成员同包中的类可见,不同包的不可见。当不设置访问权限时默认为protected类型,也就是说只有同包的可以使用。这个与C#是有区别的,C#默认private 外部不可访问。C#的protect是只有内部或有继承的子类可以调用。 internal修饰符表示同项目。this关键字的使用其实可以省略,但是this可以作为对象作为返回值。

3. == 和equals两个比较方法是不一样的。, “”==“”运算符比较的是两个对象的引用地址是否相等,而后者比较的是两个对象引用所值的内容是否相等。所以 string a = new string (abc)  和string b = new string (abc)  a == b 结果为false a.equals(b) 为 true

4.对象引用超过其作用范围,这个对象被视作垃圾。将对象赋值为null。java 垃圾回收器只能回收用new操作符创建的对象,如果某些对象不是通过new操作符在内存中创建的。将不被识别。所以要用 finalize()方法,这个方法在    Object类中protected修饰的,当我们在类中定义了该方法,在垃圾回收时首先调用该方法,并且在下一次垃圾回收动作发生时,才真正的回收对象占用的内存。 但垃圾回收和此方法不保证一定会发生,如Java虚拟机面临内存损耗待尽的情形,是不会执行垃圾回收的。所以System。gc()方法为强制启动垃圾回收器。

这里有很多设计模式:这个还需要自己去学习。

单例设计模式:保证此类的唯一性,类中有私有的构造方法,并提供一个静态的方法用于获得该类的实例。

猜你喜欢

转载自blog.csdn.net/weixin_39407066/article/details/80889374