文章目录
面向对象下
final关键字
final是最后的最终的意思,他起修饰作用,有以下四个用法
①用来修饰一个类
作用:使当前这个类不能有任何子类。即不能被继承
格式如下:
public final class 类名称 {
方法体
}
注意:一个类如果是final的,那么其中所有的成员方法都无法进行覆盖重写,下面要写的抽象类也不能用final修饰。
② 可以用来修饰一个方法
作用:当final关键字用来修饰一个方法的时候,这个方法就是最终方法,不能够被覆盖重写。
格式如下:
修饰符 final 返回值类型 方法名称(参数列表) {
方法体
}
注意:对于类、方法来说,abstract关键字和final关键字不能同时使用,因为作用相互矛盾。
③ 可以用来修饰一个局部变量
3、final关键字用于修饰局部变量
作用:当final关键字用于修饰局部变量的时候,这个局部变量就不能更改,
格式如下
① 第一种基本数据类型情况下的格式
final 基本数据类型 数据名称 = 值;
② 引用数据类型情况下的格式
final 类型 对象名 = new 类名();比如创建一个对象
注意:对于 基本类型 来说,不可改变指的是变量当中的数据不可改变,但是对于 引用类型 来说,不可改变的指的是变量当中的地址值不可改变
④ 可以用来修饰一个成员变量
4、final关键字用来修饰成员变量
对于成员变量(类的某一个属性)来说,如果使用了final关键字修饰,那么这个变量也照样是不可变的
① 由于成员变量具有默认值,所以用了final之后必须手动赋值,不会再给默认值了
② 对于final的成员变量,要么使用直接赋值,要么通过构造方法赋值,只能二选一
③ 必须保证类当中所有重载的构造方法,都最终会对final的成员变量进行赋值
④如果final修饰的属性是静态的,那么这个属性的初始化位置只能是:
1:定义时候
2:在静态代码块
不能再构造器里面赋值初始化!!!
注意
1.final类不能被继承,但是可以实例化对象
2.如果类不是final类但是里面含有final方法,则该方法不能被重写,但是可以被继承。
3.final不能修饰构造器
4.final和static搭配使用效率更高,具体格式举例如下:
public static final String sqb="孙千博";//main方法外部声明;
二、抽象类
1.抽象类特点
我们都知道普通类是一个完善的功能类,可以直接产生实例化对象,抽象类就是指在普通类的结构里面增加抽象方法的声明,拥有抽象方法的类就是抽象类,抽象类要使用abstract关键字声明。
2.抽象类的声明
代码如下
abstract class animal{//抽象类的声明
void sing(){
System.out.println("孙千博唱歌超级好听");//普通方法
}
abstract void eat();//定义一个没有方法体的抽象方法,所以类必须声明为抽象类
}
抽象类的使用规则
(1)抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public;
(2)抽象类不能直接实例化,需要依靠子类采用向上转型的方式处理;
比如我把子类dog转成animal,这样animal也可以使用dog的方法
animal animal1=new dog();
animal1.eat();//向上转形
(3)抽象类必须有子类,使用extends继承,一个子类只能继承一个抽象类;
(4)子类(如果不是抽象类)则必须覆写抽象类之中的全部抽象方法(如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。);代码如下
abstract class animal{//抽象类的声明
void sing(){
System.out.println("我唱歌超级好听");//普通方法
}
abstract void eat();//定义一个没有方法体的抽象方法,所以类必须声明为抽象类
}
class dog extends animal{
@Override
void eat() {
System.out.println("小狗在吃狗粮");//子类重写实现方法
}
}
abstract class cat extends animal{//子类声明为抽象类
}
运行结果:
小狗在吃狗粮
小狗在吃狗粮
进程已结束,退出代码0
抽象类中的构造方法
抽象类中也有构造方法,在dog和animal中添加构造方法如下,在main方法里面创建两个对象,测试构造方法结果表示不管是直接创建还是向上转型,抽象类会先执行父类的构造方法再执行子类的构造方法,代码如下:
public class absclass {
public static void main(String[] args) {
dog dog1=new dog();
animal animal1=new dog();//测试抽象方法
animal1.eat();//向上转形
}
}
abstract class animal{//抽象类的声明
animal() {
System.out.println("父类animal的构造方法");
}
void sing(){
System.out.println("我唱歌超级好听");//普通方法
}
abstract void eat();//定义一个没有方法体的抽象方法,所以类必须声明为抽象类
}
class dog extends animal{
dog() {
System.out.println("dog的构造方法");
}
@Override
void eat() {
System.out.println("小狗在吃狗粮");//子类重写实现方法
}
}
执行结果如下:
父类animal的构造方法
dog的构造方法
父类animal的构造方法
dog的构造方法
小狗在吃狗粮
进程已结束,退出代码0
可以将内部抽象类声明为static
外部不行
内部抽象类演示代码如下
abstract class animal{//抽象类的声明
static abstract class wolf{
abstract void shout();
}
}
class cat extends animal.wolf{
void shout(){
System.out.println("啊哦啊哦啊哦");
}
}
public class absclass {
public static void main(String[] args) {
cat cat=new cat();
cat.shout();
}
}
子类继承时候用父类.内部抽象类的格式继承,没有问题,可以重写内部抽象类的方法,运行结果如下:
啊哦啊哦啊哦
进程已结束,退出代码0
三丶static关键字
1、static存在的主要意义
总结了以下两点:
1.主要意义是在于创建独立于具体对象的域变量或者方法。以致于即使没有创建对象,也能使用属性和调用方法。
2.static关键字还有一个比较关键的作用就是 用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。为什么说static块可以用来优化程序性能,是因为它的特性:只会在类加载的时候执行一次。因此,很多时候会将一些只需要进行一次的初始化操作都放在static代码块中进行。
2.特点
1、被static修饰的变量或者方法属于类,不属于某一个单独的对象,被类的实例对象所共享。因为属于类,所以即使没有创建对象也可以去访问;
2.static变量值在类加载的时候分配空间,以后创建类对象的时候不会重新分配。赋值的话,是可以任意赋值的!
3.主要用法
根据目前我遇到的我总结了以下四点,下面分别举例说明:
1、修饰成员变量
static修饰的成员变量叫做静态变量,也叫做类变量,静态变量是属于这个类,而不是属于是对象。所有对象共有。
访问静态变量的方式有两种,主要推荐第一种
类名.静态变量
对象.静态变量(不推荐)
代码连同修饰成员方法的代码一同在下面展示
2、修饰成员方法
通过类名.方法名访问,注意,不能修饰构造函数
public class absclass {
public static void main(String[] args) {
animal animal1=new dog();
System.out.println(animal.a);//推荐类名.变量名
System.out.println(dog.a);//不推荐
animal.sleep();//类名.方法名访问
}
}
abstract class animal{//抽象类的声明
static int a=5;
static void sleep(){
System.out.println("遇到困难睡大觉");
}
static abstract class wolf{
abstract void shout();
}
3、静态代码块
4、修饰类【只能修饰内部类也就是静态内部类】
四丶接口
1.什么是接口
根据我的理解,Java接口,就是给出一些没有实现的方法,封装到一起,到某个类要使用的时候,再根据具体情况把这些方法写出来,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能),接口里面只有全局常量和抽象方法,接口就是100%的抽象方法;
2.基本语法
interface 接口名{
//属性
//方法
}
class 类名 interface 接口名{
自己的属性
自己的方法
必须实现的接口的方法
}
举个创建接口的栗子:
interface jiekou{
String sleepTime="八小时";//全局变量
void eat();
void sleep();
}
class people implements jiekou{
String name;
public people(String name) {
this.name = name;
}
public void eat(){//两个方法的重写
System.out.println(this.name+"一顿吃不少");
}
public void sleep(){
System.out.println(this.name+"连续睡了"+sleepTime);//全局变量的使用
}
}
class test{
public static void main(String[] args) {
String name="孙千博";
people people1=new people(name);
people1.eat();
people1.sleep();
}
}
运行结果:
孙千博一顿吃不少
孙千博连续睡了八小时
进程已结束,退出代码0
3.接口使用注意事项
1.接口中属性的访问形式:接口名.属性名
System.out.println(jiekou.sleepTime);//接口中属性的访问形式
2.接口的修饰符只能是public和默认,这点和类的修饰符是一样的
3.一个类可以同时实现多个接口,必须实现所有接口中的方法;
4.一个接口不能实现其他的类,但是可以继承多个别的接口,但是要注意,三个接口的全部方法必须都被继承的类实现,举个栗子:
interface jiekou1{
void run();
}
interface jiekou2{
void walk();
}
interface jiekou extends jiekou1,jiekou2{//多个继承
String sleepTime="八小时";//全局变量
void eat();
void sleep();
}
class people implements jiekou{
String name;
public people(String name) {
this.name = name;
}
public void eat(){//两个方法的重写
System.out.println(this.name+"一顿吃不少");
}
public void sleep(){
System.out.println(this.name+"连续睡了"+sleepTime);//全局变量的使用
}
@Override
public void run() {//必须实现
}
@Override
public void walk() {//必须实现
}
}
4.为什么不用接口
接口是完全抽象的,因为Java不像C++一样支持多继承,所以Java可以通过实现接口来弥补这个局限。接口也被用来实现解耦。
抽象类内部可能包含非final的变量,但是在接口中存在的变量一定是final,public,static的。
五丶接口和抽象类的区别
前面已经说了,抽象类就是普通类里面加上了抽象方法(可以没有方法体),接口呢,接口与抽象类主要有以下三点不同:
1.构造方法:接口没有构造方法
2.成员变量:只能是常量。默认修饰符:public static final,但是抽象类里面可以是变量
3.成员方法:jdk1.7只能是抽象的。默认修饰符:public abstract
jdk1.8可以写以default和static开头的具体方法,举个栗子(注意事项已注释):
interface jiekou extends jiekou1,jiekou2{
String sleepTime="八小时";//全局变量
void eat();
void sleep();
default void fight() {
System.out.println("加油加油");
}
static void sing(){
System.out.println("山农歌神在此");
}
}
class test{
public static void main(String[] args) {
String name="孙千博";
people people1=new people(name);
jiekou.sing();//static方法属于接口本身,接口名.方法名的格式就可以调用
people1.fight();//子类会继承接口中的普通方法,不需要重写,但是如果子类继承了多个接口,多个接口中有相同的default方法时,需要重写;
}
}
执行结果:
山农歌神在此
加油加油
进程已结束,退出代码0
4.一个类只能单继承一个类,但是可以多继承多个接口
我们选择接口或者抽象类的依据是什么?
接口和抽象类的概念不一样。接口是对动作的抽象,抽象类是对根源的抽象。当你关注一个事物的本质的时候,用抽象类;当你关注一个操作的时候,用接口。
抽象类的功能要远超过接口,但是,定义抽象类的代价高。因为高级语言来说(从实际设计上来说也是)每个类只能继承一个类。在这个类中,你必须继承或编写出其所有子类的所有共性。虽然接口在功能上会弱化许多,但是它只是针对一个动作的描述。而且你可以在一个类中同时实现多个接口。在设计阶段会降低难度。
六丶instanceof关键字
instanceof是Java的一个关键字,左边是对象,右边是类,返回类型是Boolean类型。它的具体作用是测试左边的对象是否是右边类或者该类的子类创建的实例对象,是,则返回true,否则返回false。举个栗子:
package bfw_bfr;
public class instan {
public static void main(String[] args) {
dog2 dog2=new dog2();
littledog littledog=new littledog();
System.out.println(dog2 instanceof animal2);
System.out.println(littledog instanceof animal2);//多层继承
}
}
class animal2{
}
class dog2 extends animal2{
}
class littledog extends dog2{
}
运行结果都是 true
七丶object类
Object类是所有类的父类,何一个类时候如果没有明确的继承一个父类的话,那么它就是Object的子类;所以我们在定义类的时候不需要用extends去继承object类了
该类主要有几个比较常用的方法,介绍一下:
1.toString方法
该方法用得比较多,一般我们再创建一个类的时候,要重写toString方法,让该类对象的属性信息按照我们想要的方式输出,下面我们举个栗子:
建立一个dog类,在里面重写toString方法,就可以显示一个dog对象的信息,如果不重写的话,会显示dog对象的地址;
public class dog implements Serializable,Comparable<dog>{
public static void main(String[] args) {
dog dog1=new dog("小黄",17);
dog dog2=new dog("小白",17);
dog dog3=new dog("小黑",17);
System.out.println(dog1);
System.out.println(dog2);
System.out.println(dog3);
}
String name;
int age;
public dog(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(dog o) {
return this.getName().compareTo(o.getName());
}
}
这样的话,就可以正常输出dog的信息,如下:
dog{name='小黄', age=17}
dog{name='小白', age=17}
dog{name='小黑', age=17}
进程已结束,退出代码0
如果不重写的话,不会正常显示信息,会显示地址,结果如下:
Test01.dog@4554617c
Test01.dog@74a14482
Test01.dog@1540e19d
进程已结束,退出代码0
equals方法
这个方法用来判断两个对象的内容是否相等,判断字符串是否相等的时候用它最好,用==有时候会判断出错,返回结果是Boolean类型的:
还是用上面的栗子:
public static void main(String[] args) {
dog dog1=new dog("小黄",17);
dog dog2=new dog("小白",17);
dog dog3=new dog("小黑",17);
System.out.println(dog1.equals(dog2));//判断dog两个对象的内容是否相等
//再来定义两个字符串,用equals方法判断两个字符串是否相等
String str1="孙千博";
String str2="孙千博大好人";
System.out.println(str1.equals(str2));
}
两个语句判断的结果都是false;
八丶多态
说明以下,我看学长的面向对象 下里面有多态总结部分,但是我个人在第二周的总结里面已经详细的写了多态的内容了,这里就没法重新写了;
总结
java面向对象部分到此结束!