JavaSE进阶

final关键字

final是java中的一个关键字
final用于变量声明,被声明的变量的值将无法改变
子类能继承超类,能对超类的功能进行拓展,如果不希望子类对超类进行拓展 可以给超类加final关键字,这样子类就无法继承超类了

final修饰的类无法被继承

 final class A{
}
class B extends A{
}
//java: 无法从最终A进行继承

final也可以修饰变量;

  public static void main(String[] args) {
       final double pi=3.14;
       pi=2.5;
        System.out.println(pi);
    }
    //java: 无法为最终变量pi分配值

如果被final修饰的是一个引用也不能二次赋值
但可以利用类中的方法去改变类中的变量

class A{
    int a;
    public A() { }
    public int getA() {return a;}

    public A(int a) { this.a = a; }

    public void fu(int a) { this.a=a; }
}
public class jihuo{
    public static void main(String[] args) {
        final A a=new A(10);
        a.fu(20);
        a=new A(5);//报错
    }
}
//java: 无法为最终变量a分配值

超类中被final修饰的方法无法被子类重写和覆盖

class A{
    public final void printl()
    {
        System.out.println("jykglyu");
    }
}
class B extends A{
    public void printl()
    {
    	System.out.println("rdyt");
    }
}
//java: B中的printl()无法覆盖A中的printl()
  //被覆盖的方法为final

补充:超类调用子类的方法 需要向下转型

class A{
    public  void printl()
    {
        System.out.println("jykglyu");
    }
}
class B extends A{
    public void domel()
    {
        System.out.println("hello world");
    }
}
public class jihuo{
    public static void main(String[] args) {
        A a=new B();
        //a.domel();
        //报错  
        if(a instanceof B)
        {
            B b1=(B)a;
            ((B) a).domel();
            b1.domel();
        }
    }
}

补充:当类中的变量没有初始化时,类中的构造函数会将变量默认设置为0;但加了final的变量不能被构造函数初始化
错误

class A{
    int country;
    public int getCountry() { return country; }
}
public class jihuo{
    public static void main(String[] args) {
         A a=new A();
        System.out.println(a.getCountry());
    }
}

错误

class A{
    final int country;
    public int getCountry() { return country; }
}
public class jihuo{
    public static void main(String[] args) {
         A a=new A();
        System.out.println(a.getCountry());
    }
}

所以程序员必须手动初始化final定义的变量

抽象类

在普通类的基础上扩充了一些抽象方法(0~n)的类(抽象类是普通类的超集),使用abstract关键字定义。
抽象类不能直接产生实例化对象,因为抽象类是“半成品”,无法直接使用。不能直接new。
抽象类abstract不能与final一起使用。
抽象类的子类可以是抽象类也可以是普通类。
抽象方法:使用abstract 关键字定义并且没有方法体的方法。抽象方法必须在抽象类中,但抽象类中可以没有抽象方法。

抽象类中的抽象方法不能有主体

abstract class A{
    public  abstract void move(){}
}//报错
//java: 抽象方法不能有主体

一个非抽象类继承抽象类必须覆盖抽象类中的抽象方法,或者将子类改为抽象类

abstract class A{
    public  abstract void move();
}
 class B extends A{
 //public void move(){}
}
//报错
//java: B不是抽象的, 并且未覆盖A中的抽象方法move()

在主函数中可以通过父类型引用指向子类型对象
A a=new B();
a.move();
如果B 也是抽象类 那么就可以不用重写A中的方法
一道面试题:java中没有方法体的方法都是抽象方法(T/F)
答案:F
解释:例如Object类中就有很多方法没有方法体,但他们多不是抽象方法,例如:public native inthashCode();这个方法是调用C++写的动态链接库程序。前面没有abstract。有一个native,表示调用JVM本地程序。

接口

接口基础语法
接口也是一种“引用数据类型”。编译之后也是一个字节码文件
接口是完全抽象的。是一种特殊的抽象类。
接口支持多继承,一个抽象类支持继承多个父类
接口中包含两部分,一部分是常量,一部分是抽象方法
接口中的方法不能有方法体

public class text1 {
    public static void main(String[] args) {
        System.out.println(A.PI);//调用接口中的变量,接口中的变量不能改变
    }
}
interface C extends A,B{//一个接口支持多继承
	public static final double PI=3.1415926;//接口中常量可以省略public static final
    public abstract int moth();//方法名可以省略public abstract
}
package Interface;

public class text2 {
    public static void main(String[] args) {
        FoudMenu cooker=new AmerCook();
        Custermor custermor=new Custermor(cooker);
        custermor.redor();
        FoudMenu cooker1=new ChinaCook();
        Custermor custermor1=new Custermor(cooker1);
        custermor1.redor();
    }
}
class ChinaCook implements FoudMenu {
    public void xhscjd(){
        System.out.println("我是中餐厨师我会西红柿炒鸡蛋");
    }
    public void yxrs()
    {
        System.out.println("我是中餐厨师我会做鱼香肉丝");
    }
}
class AmerCook implements FoudMenu{
    public void xhscjd(){
        System.out.println("我是西餐厨师我不会西红柿炒鸡蛋");
    }
    public void yxrs()
    {
        System.out.println("我是西餐厨师我不会做鱼香肉丝");
    }
}
class Custermor{
    private FoudMenu foodmenu;
    public Custermor(){ }
    public Custermor(FoudMenu foodmenu)
    {
        this.foodmenu=foodmenu;
    }
    public void setFoodmenu(FoudMenu foodmenu){
        this.foodmenu=foodmenu;
    }
    public FoudMenu getFoodmenu(){
        return this.foodmenu;
    }
    public void redor(){
        foodmenu.xhscjd();
        foodmenu.yxrs();
    }
}
interface FoudMenu{
    void xhscjd();
    void yxrs();
}

抽象类与接口的区别

类与类之间叫继承,类与接口之间叫做实现
继承使用extends,实现使用implements关键字
接口是一个抽象概念,
可插拔性

package Interface;
public class text2 {
    public static void main(String[] args) {
        Flyable f=new Cat();
        f.fly();
        Flyable f1=new Snake();
        f1.fly();
        Flyable f2=new Pig();
        f2.fly();
    }
}
interface Flyable{
    void fly();
}
class Animal{}
class Cat extends Animal implements Flyable{
    public void fly()
    {
        System.out.println("我是一只神奇的星猫");
    }
}
class Snake extends Animal implements Flyable{
    public void fly(){
        System.out.println("我是一条蛇,我不会飞");
    }
}
class Pig extends Animal implements Flyable{
    public void fly()
    {
        System.out.println("我是一只猪,我想飞");
    }
}
/*我是一只神奇的星猫
我是一条蛇,我不会飞 
我是一只猪,我想飞*/

在这里插入图片描述
补充:
1.一个类可以实现多个接口,与之相反一个类只能继承一个父类
2.接口结合多态使用才能降低程序的耦合度
3.(is a)继承,(has a)关联,(like a)实现在这里插入图片描述
抽象类是半抽象的。
接口是完全抽象。

抽象类中有构造方法。
接口中没有构造方法。

类与类之间只能单继承。
接口与接口之间支持多继承。

接口中只存在常量与

package和import

package出现在java源文件的第一行
一个Java源代码程序就是一个编译单元,每个编译单元都必须有一个后缀名.java,而在编译单元内有且仅有一个public类,否则编译器就不会接受。该public类的名称必须与文件的名称相同(包括大小写,但不包括后缀名.java)
假设文件名称TelephonyManager,就有一个公共类TelephonyManager

访问控制权限

在这里插入图片描述
访问控制权限可以修饰什么
属性(四个都可以)
方法(四个都可以)
类(只能由public和默认修饰,其他的不行 )
接口(只能由public和默认修饰,其他的不行)

Object类

JDK类库的根类是Object
当使用equals()时默认比较的是内存地址;
在java中字符串和引用数据类型的比较一般采用equals()

System.out.println("b" == "b");	//true
System.out.println("a".equals("a")); //true
System.out.println("a".equals(new String("a"))); //true
System.out.println("a" == new String("a"));	//false
System.out.println(new String("a") == new String("a")); //false
System.out.println(new String("a").equals(new String("a"))); //true

数据类型的比较采用“==”
以后所有类的equals()方法需要重写,因为Object中的equals()方法比较的是两个对象的内存地址,我们一般会比较内容,所以需要重写,如下所示

package Objecttext;
import java.util.TreeMap;
public class text {
    public static void main(String[] args) {
        Mytext t = new Mytext();
        Mytext t1 = new Mytext();
        String s = t.toString();
        System.out.println(s);
        System.out.println(t1 == t);
        System.out.println(t1.equals(t));
    }
}
class Mytext {
    int id = 1000;
    int age = 55;
    String name = "hvhvhjvjuyyswsyiuliuts";
    public Mytext() {}
    public Mytext(int id, int age, String name) {
        this.id = id;
        this.age = age;
        this.name = name;
    }
    public int getId() {return id;}
    public void setId(int id) {this.id = id;}
    public int getAge() {return age;}
    public void setAge(int age) {this.age = age;}
    public String getName() {return name;}
    public void setName(String name) {this.name = name;}
    @Override
    public String toString() {
        return "Mytext{" +
                "id=" + id +
                ", age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
    public boolean equals(Object obj) {
        int id = this.id;
        int age = this.age;
        String name = this.name;
        if (obj instanceof Mytext) {
            Mytext t = (Mytext) obj;
            int id1 = t.id;
            int age1 = t.age;
            String name1 = t.name;
            if (id == id1 && age == age1 && name == name1) {
                return true;
            }
        } return false;
    }
}
//输出
//Mytext{id=1000, age=55, name='hvhvhjvjuyyswsyiuliuts'}
//false
//true

基本数据类型的比较使用“==”;
对象与对象的比较使用equals();

object中equals重写并对两个相同的对象进行比较

package Objecttext;

public class text01 {
    public static void main(String[] args){
        User u1=new User("zhangsan",new Address("bjs","dxq","356856"));
        User u2=new User("zhangsan",new Address("bjs","dxq","356856"));
        User u3=new User("LiShi",new Address("bjs","dxq","356856"));
        System.out.println(u1.equals(u3));
        System.out.println(u1.equals(u2));
    }
}
class User
{
    String name;
    Address addr;
    public User() {}
    public User(String name,  Address addr) {
        this.name = name;

        this.addr = addr;
    }
    public boolean equals(Object obj)
    {
        if (obj==null||!(obj instanceof User))
            return false;
        if (this==obj)
            return true;
        User u=(User)obj;
        if (this.name.equals(u.name)&&this.addr.equals(u.addr))
        {
            return true;
        }
        return false;

    }
}
class Address{
    String city;
    String street;
    String zipcode;
    public Address(){}
    public Address(String city, String street, String zipcode) {
        this.city = city;
        this.street = street;
        this.zipcode = zipcode;
    }
    public boolean equals(Object obj )
    {
        if (obj==null||!(obj instanceof Address))
            return false;
        if (this==obj)
            return true;
        Address a=(Address)obj;
        if (this.city.equals(a.city)&&this.street.equals(a.street)&&this.zipcode.equals(a.zipcode))
            return true;
        return false;

    }
}
//结果返回true

关于object类中的finalize()方法。
在Object类的原码中:

protected void finalize() throws  Throwable{}

finalize()方法没有方法体, 里面没有代码,而且这个方法是用protected修饰的。
这个方法不需要程序员调用,jvm垃圾回收器负责调用这个方法,当一个java对象即将被垃圾回收器回收时垃圾回收器负责调用finalize()方法。
它不像equals()和toString()需要你写代码调用,finalize()只需要你重写,重写完以后自动会有程序来调用,GC调用finalize()方法

静态代码块的作用是什么?
static{}
静态代码块在类加载的时刻执行,并且只执行一次。是一个加载时机,final则是一个垃圾回收时机。

java中的垃圾回收器不轻易启动,垃圾太少或时间没到都不启动

package Objecttext;

public class text02 {
    public static void main(String[] args) {
        //创建对象
       for (int i=0;i<1000000;i++)
       {
           nume f=new nume();
           f=null;
           System.gc();//垃圾回收器建议启动方法
       }
    }
}
class nume{
    //重写finalize()方法
    //nume类型的对象被垃圾回收器回收的时候垃圾回收器负责调用f.finzlize();
    protected void finalize() throws Throwable{
        System.out.println("即将被回收");
    }
}
//即将被回收
//即将被回收.........

hashCode方法:
在Object中的hashCode方法是怎么样的?
public native inthashCode();
这个方法不是抽象方法,带有native,是调用底层C++程序。
hashCode返回的是哈希码:
实际上就是一个java对象的内存地址,经过哈希算法,得出的一个值。
所以hashCode()方法的执行结果可以等同于一个java对象的内存地址。

public class text03 {
    public static void main(String[] args) {
        Object o=new Object();
        int hc=o.hashCode();
        nume n=new nume();
        int hs=n.hashCode();
        System.out.println(hc);
        System.out.println(hs);
    }
}
class nump{
}

匿名内部类

普通接口实现加法计算

public class Main {
    public static void main(String[] args) {
	// write your code here
        mymath m=new mymath();
        comp c=new Compler();
        m.mysun(c,1,3);
    }
}
interface comp{
    int sum(int x,int y);
}
class Compler implements comp{
    public int sum(int x,int y){
        return x+y;
    }
}
class mymath
{
    public void mysun(comp c,int x,int y)
    {
        int ret=c.sum(x,y);
        System.out.println(x+" + "+y+"="+ret);
    }
}

利用匿名内部类实现加法计算

public class Main {
    public static void main(String[] args) {
        mymath m=new mymath();

        m.mysun(new comp(){
          public   int sum(int x,int y){
              return x+y;
          }
        },1,3);
    }
}
interface comp{
    int sum(int x,int y);
}
class mymath
{
    public void mysun(comp c,int x,int y)
    {
        int ret=c.sum(x,y);
        System.out.println(x+" + "+y+"="+ret);
    }
}

hashmap

双列集合

自定义的枚举需要重写hashcode和equals吗
不需要

Map<Integer, Integer> map = new HashMap<Integer, Integer>();  
  
//遍历map中的键  
  
for (Integer key : map.keySet()) {  
  
    System.out.println("Key = " + key);  
  
}  
  
//遍历map中的值  
  
for (Integer value : map.values()) {  
  
    System.out.println("Value = " + value);  
  
} 

比较器的使用

package test;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Arrays;

public class ClassWork {
    public static void main(String[] args) {
       Goods [] goods={new Goods("pg",10),new Goods("xj",5),new Goods("sg",15)};
        Arrays.sort(goods);
        for (Goods i:goods
             ) {
            System.out.println(i);
        }


    }
}

@NoArgsConstructor
@AllArgsConstructor
@Data
class Goods implements Comparable<Goods>{
    private String  name;
    private Integer weight;

    @Override
    public int compareTo(Goods o) {
        if (this.weight>=o.weight)
        {
            return 1;
        }
        return -1;
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值