GVKun编程网logo

java -- static/final/abstract

1

以上就是给各位分享java--static/final/abstract,同时本文还将给你拓展4.11abstract类和abstract方法、5-2Java中的static使用之静态变量;;Java

以上就是给各位分享java -- static/final/abstract,同时本文还将给你拓展4.11 abstract 类和 abstract 方法、5-2 Java 中的 static 使用之静态变量 ;;Java 中的 static 使用之静态方法;;Java 中的 static 使用之静态初始化块、Abstract vals && Abstract vars、abstract 类和 abstract 方法等相关知识,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

java -- static/final/abstract

java -- static/final/abstract

#1.static
当一个方法或者变量需要初始化时被加载,或者是经常被调用的时候,可以使用 static 修饰它们。 弊处是:初始化被加载,比较占用内存。
java 语言中没有 全局变量 这个概念,可以使用 static 表示 "全局变量 (或方法)",因为被 static 修饰的变量 / 方法不依赖于任何类的实例,它被所有类的实例共享。

static 修饰符可以与 变量、方法、类 (内部类) 一起使用,表示 "静态" 的。
静态变量 / 方法通过 类名 来访问,因此它们也被称作类变量 / 类方法。
实例变量 / 方法需要通过类的实例来访问。
##1. 静态变量 静态变量属于类,不是对象,因此无需创建类的实例就可以访问它。编译器只会给静态变量分配一个内存空间,虽然会有多个实例 (类每调用一次),但这些实例共享该内存。实例变量则不同,每创建一个对象,都会被分配一次内存空间,不同实例之间的内存相互独立,互不影响,改变 a 的实例变量不会影响 b 的实例变量。
static 修饰的变量在类加载的时候就会被初始化,也就是说,只要类被加载,不管是否用了这个 static 变量,它都会被初始化。以后在生成类的实例 (类名。变量) 时,将共享这个变量,任何一个对象修改 静态变量,都会影响其他类对它的使用。

静态变量与实例变量的区别
1. 静态变量需要被 static 修饰,实例变量不需要。
2. 静态变量只会被加载一次,即只分配一次内存,可以用类名直接访问,所有的类都可以操作静态变量,因此静态变量的值可能会被各个类修改,即所有的类共享该变量;对于属性变量,没创建一个实例,都会为该实例的属性分配一次内存,因此各个实例的属性之间互不影响,即修改了实例 A 的 cc 属性不会影响实例 B 的 cc 属性 (备注:实例 A 与实例 B 同属于一个类)。
3. 静态变量使用场景
1 > 各个对象之间共享该变量 (多线程)
2 > 经常需要访问该变量
##2. 静态方法
1. 静态方法同静态变量一样,也是被各个类的实例共享。因此,静态方法中不能出现 this 与 super 关键字。
2. 静态方法不能操作它所属类的非静态变量。
静态方法使用场景:
1. 一个方法不需要操作对象,其所需参数都是显式参数提供 (例如:Math.pow ())。
2. 一个方法只需要访问类的静态变量。

static 和 final 组合使用
static 与 final 组合修饰的变量 / 方法 / 类,可以理解为 "全局常量 / 方法 / 类"。
很明显,static 修饰的变量可以被所有类的实例使用,因此表示 "全局";final 修饰的变量值不可以被改变,因此表示 "常量"。
static final 变量:表示该变量一旦给定值,就不可以修改。
static final 方法:表示该方法不可以被覆盖,即不能被重写。
static final 类:该类是一个内部类,该类不能被继承。

#2.final
final 可以修饰类、方法、变量。表示 “最终” 的意思。
1.final 修饰的类不能被继承
2.final 修饰的方法不能被子类重写
3.final 修饰的变量,即为常量,只能被赋值一次

#3.abstract
抽象修饰符,它可以修饰类和方法。
abstract 修饰类:使这个类变成一个抽象类,即这个类不能实例化对象。它需要被子类继承,并实现其方法。
abstract 修饰方法:使这个方法变成抽象方法,即该方法只有声明没有实现,需要在子类中实现。
备注:
1. 存在抽象方法的类一定是抽象类;反过来,抽象类中不一定全部都是抽象方法,它可以有实现的方法。
2. 子类继承抽象类后,如果需要实例化对象,则该子类必须要实现父类所有的方法;否则,该子类也必须是抽象类 (即子类如果没有完全覆写抽象父类的方法,盖子类也必须是抽象类;只有完全覆写了,该子类才可以实例化对象)。

4.11 abstract 类和 abstract 方法

4.11 abstract 类和 abstract 方法

用关键字 abstract 修饰的类称为 abstract 类(抽象类)。如:
abstract class A
{   …
}
特点:
1.abstract 类中可以有 abstract 方法
    对于 abstract 方法,只允许声明,不允许实现,而且不允许 final 修饰 abstract 方法。
    abstract 类也可以没有 abstract 方法。
2.abstract 类不能用 new 运算符创建对象
    abstract 类不能用 new 运算符创建对象,需产生子类,由子类创建对象,如果一个类是 abstract 类的子类,必须实现父类的 abstract 方法,这就是为什么不允许使用 final 修饰 abstract 方法的原因
例:
abstract class A{        
    abstract int min(int x,int y);
    int max(int x,int y){        
        return x>y?x:y;                
    }
}
class B extends A{        
    int min(int x,int y){        
        return x<y?x:y;
    }
}
public class AbstractExample{        
    public static void main(String args[]){        
        A a;
        //a=new A();非法,抽象类不能实例化
        B b = new B();
        int max = b.max(11,22);
        int min = b.min(11,22);
        System.out.println("max="+max+" min="+min);
        a = b;
        max = a.max(11,22);
        System.out.println("max="+max);
    }
}
abstract 只关心它的子类是否具有某种功能并不关心功能的具体行为,抽象类的抽象方法可以强制子类必须给出这些方法的具体实现

5-2 Java 中的 static 使用之静态变量 ;;Java 中的 static 使用之静态方法;;Java 中的 static 使用之静态初始化块

5-2 Java 中的 static 使用之静态变量 ;;Java 中的 static 使用之静态方法;;Java 中的 static 使用之静态初始化块

1.Java 中被 static 修饰的成员称为静态成员或类成员。它属于整个类所有,而不是某个对象所有,即被类的所有对象所共享。静态成员可以使用类名直接访问,也可以使用对象名进行访问。当然,鉴于他作用的特殊性更推荐用类名访问

使用 static 可以修饰变量、方法和代码块。

    

2. 与静态变量一样,我们也可以使用 static 修饰方法,称为静态方法或类方法。其实之前我们一直写的 main 方法就是静态方法。静态方法的使用如:

         

注意:

1、 静态方法中可以直接调用同类中的静态成员,但不能直接调用非静态成员。如:

    

如果希望在静态方法中调用非静态变量,可以通过创建类的对象,然后通过对象来访问非静态变量。如:

2、 在普通成员方法中,则可以直接访问同类的非静态变量和静态变量,如下所示:

3、 静态方法中不能直接调用非静态方法,需要通过对象来访问非静态方法。如:

          

3.Java 中的 static 使用之静态初始化块

Java 中可以通过初始化块进行数据赋值。如:

   在类的声明中,可以包含多个初始化块,当创建类的实例时,就会依次执行这些代码块。如果使用 static 修饰初始化块,就称为静态初始化块。

注意:静态初始化块只在类加载时执行,且只会执行一次,同时静态初始化块只能给静态变量赋值,不能初始化普通的成员变量  

 

 

 

 

 

 

Abstract vals && Abstract vars

Abstract vals && Abstract vars

Abstract vals && Abstract vars

在 scala 中抽象类和特质都可以定义抽象的成员变量。

Abstract vals && Abstract vars

abstract class Abstract {
  type T

  def transform(x: T): T

  val initial: T
  var current: T
}

class Concrete extends Abstract {
  override type T = String

  override def transform(x: T): T = x + x

  //在Java里这是final变量,所以必须要初始化赋值
  override val initial: T = "string"
  //在Java里这个private类型变量,在scala中可以yoga下划线赋值
  override var current: T = _
}

object Main9 {
  def main(args: Array[String]): Unit = {
    val c = new Concrete
    println(c.initial) //string
    println(c.current) //null
  }
}

如上的示例,定义两个抽象的成员变量,

val initial: T
var current: T

同时实现类实现抽象类的时候必须要赋值重写。在 Java 里看起来很怪,那么在 Java 里是如何实现的呢,通过 javap 反编译看一下

C:\WorkSpace5-gitosc\scala-sample\out\production\scala-sample\com\usoft3>javap -p Abstract.class
Compiled from "test.scala"
public abstract class com.usoft3.Abstract {
  public abstract java.lang.Object transform(java.lang.Object);
  public abstract java.lang.Object initial();
  public abstract java.lang.Object current();
  public abstract void current_$eq(java.lang.Object);
  public com.usoft3.Abstract();
}

C:\WorkSpace5-gitosc\scala-sample\out\production\scala-sample\com\usoft3>javap -p Concrete.class
Compiled from "test.scala"
public class com.usoft3.Concrete extends com.usoft3.Abstract {
  private final java.lang.String initial;
  private java.lang.String current;
  public java.lang.String transform(java.lang.String);
  public java.lang.String initial();
  public java.lang.String current();
  public void current_$eq(java.lang.String);
  public void current_$eq(java.lang.Object);
  public java.lang.Object current();
  public java.lang.Object initial();
  public java.lang.Object transform(java.lang.Object);
  public com.usoft3.Concrete();
}

其实在 scala 中定义的抽象字段在反编译后的 java 类中,其实就是抽象方法,

public abstract java.lang.Object initial();
public abstract java.lang.Object current();

那么也就不难理解了。


Initializing abstract vals

如下定义的抽象类中含有两个抽象变量

abstract class Abstract {
  val numerArg: Int
  val denomArg: Int
}

javap 反编译 Abstract 抽象类

C:\WorkSpace5-gitosc\scala-sample\out\production\scala-sample\com\usoft4>javap -p Abstract.class
Compiled from "test.scala"
public abstract class com.usoft4.Abstract {
  public abstract int numerArg();
  public abstract int denomArg();
  public com.usoft4.Abstract();
}

scala 中实现抽象类的方式最简单的如下,同时也必须重写抽象变量

new Abstract {
  override val denomArg: Int = 1
  override val numerArg: Int = 2
}

我们打印一下这个实现类的 className

println(new Abstract {
  override val denomArg: Int = 1
  override val numerArg: Int = 2
}.getClass.getName)

com.usoft4.Main9$$anon$1,javap 反编译

C:\WorkSpace5-gitosc\scala-sample\out\production\scala-sample\com\usoft4>javap -p Main9$$anon$1.class
Compiled from "test.scala"
public final class com.usoft4.Main9$$anon$1 extends com.usoft4.Abstract {
  private final int denomArg;
  private final int numerArg;
  public int denomArg();
  public int numerArg();
  public com.usoft4.Main9$$anon$1();
}

反编译的 Abstract 抽象类中是没有定义的成员变量的,只是在抽象类的实现类中出现了父类的成员变量。

这其实就是 Java 中的匿名类的概念。

=================END=================

abstract 类和 abstract 方法

abstract 类和 abstract 方法

可以使用 abstract 来修饰一个类或者方法。

用 abstract 修饰的类表示这个类是一个抽象类,用 abstract 修饰的方法表示这个方法是一个抽象方法。

抽象类不能被实例化。

抽象方法是只有方法声明,而没有方法的实现内容。

abstract 抽象类

可以使用 abstract 来修饰一个类。

用 abstract 修饰的类表示这个类是一个抽象类。

抽象类不能被实例化。

这是一个简单抽象的方法,如果它被直接实例化,系统会报错。


<?php  
//定义一个抽象类  
abstract class User  
{  
    public function __toString() {  
        return get_class($this);  
    }   
}  
//实例化这个类会出现错误  
echo new User();  
?>

 下面例子的 NormalUser 继承自 User 类,就可以被实例化了。


<?php  
//定义一个抽象类  
abstract class User  
{  
    public function __toString() {  
        return get_class($this);  
    }   
}  
//实例化这个类会出现错误  
echo new User();  
class NormalUser extends User  
{  
}  
$a = new NormalUser();  
echo "这个类" . $a . "的实例";  
?>

 

单独设置一个抽象类是没有意义的,只有有了抽象方法,抽象类才有了血肉。下面介绍抽象方法。

abstract 抽象方法

用 abstract 修饰的类表示这个方法是一个抽象方法。

抽象方法,只有方法的声明部分,没有方法体。

抽象方法没有 {} ,而采用;结束。

一个类中,只要有一个抽象方法,这个类必须被声明为抽象类。

抽象方法在子类中必须被重写。

下面是一个抽象类,其中有两个抽象方法,分别是 setSal () 和 getSal ()。用来取回 $sal 员工的工资。



<?php  
abstract class User  
{  
    protected $sal = 0;  
    //这里定义的抽象方法。  
    //注意抽象方法没有方法体,而且方法结束使用 ; 号。  
    abstract function getSal();  
    abstract function setSal();  
    //定义它的__tostring方法  
    public function __toString() {  
        return get_class($this);  
    }   
}   
?>

 既然 User 类不能被直接继承,我们写一个 NormalUser 类继承自 User 类。当我们写成如下代码时,系统会报错。 这个错误告诉我们,在 User 类中有两个抽象方法,我们必须在子类中重写这两个方法。


<?php  
abstract class User  
{  
    protected $sal = 0;  
    //这里定义的抽象方法。  
    //注意抽象方法没有方法体,而且方法结束使用 ; 号。  
    abstract function getSal();  
    abstract function setSal();  
    //定义它的__tostring方法  
    public function __toString() {  
        return get_class($this);  
    }   
}  
class NormalUser extends User  
{  
}  
?>

下面例子,重写了这两个方法,虽然方法体里面 {} 的内容是空的,也算重写了这个方法。注意看重写方法的参数名称,这里只要参数数量一致就可以,不要求参数的名称必须一致。 


<?php  
abstract class User  
{  
    protected $sal = 0;  
    //这里定义的抽象方法。  
    //注意抽象方法没有方法体,而且方法结束使用;号。  
    abstract function getSal();  
    abstract function setSal();  
    //定义它的__tostring方法  
    public function __toString() {  
        return get_class($this);  
    }   
}  
class NormalUser extends User  
{  
    function getSal() {  
    }  
    function setSal($sal) {   
    }  
}  
    //这样就不会出错了。  
?>

 

下面 19-21 行,三种写重写的方式都会报错。

19 行,缺少参数。

20 行,参数又多了。

21 行,参数类型不对。(这种写法在以后章节介绍)

一个类中,如果有一个抽象方法,这个类必须被声明为抽象类。

下面这个类不是抽象类,其中定义了一个抽象方法,会报错。




<?php  
class User  
{  
    protected $sal = 0;  
    //这里定义的抽象方法。  
    //注意抽象方法没有方法体,而且方法结束使用;号。  
    abstract function getSal();  
    abstract function setSal();  
    //定义它的__tostring方法  
    public function __toString() {  
        return get_class($this);  
    }   
}  
    //这个类中有两个抽象方法,如果这个类不是抽象的。会报错  
?>

 

抽象类继承抽象类

抽象类继承另外一个抽象类时,不用重写其中的抽象方法。

抽象类中,不能重写抽象父类的抽象方法。

这样的用法,可以理解为对抽象类的扩展

下面的例子,演示了一个抽象类继承自另外一个抽象类时,不需要重写其中的抽象方法。



<?php  
abstract class User  
{  
    protected $sal = 0;  
    abstract function getSal();  
    abstract function setSal($sal);   
}  
abstract class VipUser extends User  
{  
}  
?>

 

抽象类在被继承后,其中的抽象方法不能被重写。

如果发生重写,系统会报错。




<?php  
abstract class User  
{  
    protected $sal = 0;  
    abstract function getSal();  
    abstract function setSal($sal);   
}  
abstract class VipUser extends User  
{  
    abstract function setSal();   
}  
?>

 抽象类继承抽象类,目的对抽象类的扩展。


<?php  
abstract class User  
{  
    protected $sal = 0;  
    abstract function getSal();  
    abstract function setSal($sal);   
}  
abstract class VipUser extends User  
{  
    protected $commision = 0;  
    abstract function getCommision();  
    abstract function setCommision();  
}  
?>

 

在 PHP5.1 中,抽象类中支持静态抽象方法。下面这个例子,看到静态抽象方法可以声明。实现这个方法时,必须是静态的方法。

静态抽象方法

在 PHP5.1 中,抽象类中支持静态抽象方法。下面这个例子,看到静态抽象方法可以声明。实现这个方法时,必须是静态的方法。




<?php  
abstract class User  
{  
    protected static  $sal = 0;  
    static abstract function getSal();  
    static abstract function setSal($sal);   
}  
class VipUser extends User  
{  
    static function getSal() {  
        return self::$sal;  
    }  
    static function setSal($sal) {  
        self::$sal = $sal;  
    }  
}  
VipUser::setSal(100);  
echo "you sal is " . VipUser::getSal();  
?>  
//这里的抽象方法好像没有问题

 

关于java -- static/final/abstract的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于4.11 abstract 类和 abstract 方法、5-2 Java 中的 static 使用之静态变量 ;;Java 中的 static 使用之静态方法;;Java 中的 static 使用之静态初始化块、Abstract vals && Abstract vars、abstract 类和 abstract 方法的相关知识,请在本站寻找。

本文标签: