「java非虚方法」JAVA虚函数

博主:adminadmin 2023-01-09 09:06:09 993

本篇文章给大家谈谈java非虚方法,以及JAVA虚函数对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

java 中abstract和virtual的区别是什么?有什么用处?

virtual是C#中的吧 你是问C#中abstract和virtual的区别吧

虚方法:由virtual声明,它允许在派生类中被重写,要重写方法,必须先声名为virtual

public class myclass

{

public virtual int myint()

{

函数体;

}

}

class myclass1:myclass

{

public override int myint()

{

函数体1;

}

}

抽象类、抽象函数:由abstract声明,在抽象类中可以定义抽象方法,抽象方法基本没有执行代码,派生类必须重写它,提供其执行代码

public abstract class myclass

{

public abstract int myint();

}

public class myclass1:myclass

{

public override int myint()

{

函数体;

}

}

两者不同

为什么Java中的函数默认是虚拟函数

其实这个主要还是C#的问题而非Java问题。 多态的实现就是靠后绑定。当从父类中继承的时候,虚函数和被继承的函数具有相同的签名。在运行期间根据情况(参数,返回值)决定调用函数的入口地址。 Java中“所有函数默认为虚函数”,也就是说所有的方法(除final)默认都是可以继承的。 java代码class A {public void func() { System.out.println(A);}} class B extends A { public void func() { System.out.println(B);}} class C extends A {} class Test { public static void main(String[] args) { A a = new A(); A b = new B(); A c = new C(); a.func(); //A b.func(); //B c.func(); //A}}C#代码usingSystem;namespaceSouthWolf{classA{publicvirtualvoidFunc(){Console.WriteLine(A);}}classB:A{publicoverridevoidFunc()//注意override,表明重新实现了虚函数{Console.WriteLine(B);}}classC:B{}classD:A{publicnewvoidFunc()//注意new,表明覆盖父类里的同名方法,而不是重新实现{Console.WriteLine(D);}}classprogram{staticvoidMain(){Aa;Ab;Ac;Ad;a=newA();b=newB();c=newC();d=newD(); a.Func();//执行a.Func:1.先检查申明类A2.检查到是虚拟方法3.转去检查实例类A,就为本身4.执行实例类A中的方法5.输出结果A b.Func();//执行b.Func:1.先检查申明类A2.检查到是虚拟方法3.转去检查实例类B,有重载的4.执行实例类B中的方法5.输出结果B c.Func();//执行c.Func:1.先检查申明类A2.检查到是虚拟方法3.转去检查实例类C,无重载的4.转去检查类C的父类B,有重载的5.执行父类B中的Func方法5.输出结果B d.Func();//执行d.Func:1.先检查申明类A2.检查到是虚拟方法3.转去检查实例类D,无重载的(这个地方要注意了,虽然D里有实现Func(),但没有使用override关键字,所以不会被认为是重载)4.转去检查类D的父类A,就为本身5.执行父类A中的Func方法5.输出结果ADd1=newD();d1.Func();//执行D类里的Func(),输出结果FuncInD Console.ReadLine();}}} 1、当调用一个对象的函数时,系统会直接去检查这个对象申明定义的类,即申明类,看所调用的函数是否为虚函数; 2、如果不是虚函数,那么它就直接执行该函数。而如果有virtual关键字,也就是一个虚函数,那么这个时候它就不会立刻执行该函数了,而是转去检查对象的实例类。 3、在这个实例类里,他会检查这个实例类的定义中是否有重新实现该虚函数(通过override关键字),如果是有,那么OK,它就不会再找了,而马上执行该实例类中的这个重新实现的函数。而如果没有的话,系统就会不停地往上找实例类的父类,并对父类重复刚才在实例类里的检查,直到找到第一个重载了该虚函数的父类为止,然后执行该父类里重载后的函数。 Java中则是根据同名函数的签名(参数列表/返回值)判断是否为多态/重载。

java里面有虚方法么

java中没有明确说明什么是虚方法;

虚方法是C++来的

java虚方法你可以理解为java里所有被overriding的方法都是virtual的,所有重写的方法都是override的

class Program

{

static void Main(string[] args)

{

Person p = new Person("test1");

p = Person.Find("Aseven");

int Age = p.GetAge();

p.Say();

Console.ReadKey();

}

}

public class Person

{

private string _name;

private int _age;

public string Name

{

get { return _name; }

set { _name = value; }

}

public virtual void Say()

{

Console.WriteLine("******");

}

public static Person Find(string name)

{

return new Chinese(name);//模拟数据库查找

}

public int GetAge()

{

return _age;

}

public Person() { }

public Person(string name)

{

this._name = name;

}

}

public class Chinese : Person

{

public Chinese(string name)

{

this.Name = name;

}

public override void Say()

{

Console.WriteLine("你好!");

}

}

public class American : Person

{

public American(string name)

{

this.Name = name;

}

public override void Say()

{

Console.WriteLine("Hello!");

}

}

在Java 中非static方法如何调用??

类名.方法调用 是用来调用静态方法的 也就是static的方法

需要像一楼说的 先实例化 再调用

例如:

public class Test{

public void print(){

System.out.println("test");

}

public static void main(String args[]){

Test test = new Test();

test.print();

}

}

关于java抽象方法

下面是抽象方法声明时采用的语法:abstract void f();

如果从一个抽象类继承,而且想生成新类型的一个对象,就必须为基础类中的所有抽象方法提供方法定义。如果不这样做(完全可以选择不做),则衍生类也会是抽象的,而且编译器会强迫我们用abstract 关键字标志那个类的“抽象”本质。即使不包括任何abstract 方法,亦可将一个类声明成“抽象类”。如果一个类没必要拥有任何抽象方法,而且我们想禁止那个类的所有实例,这种能力就会显得非常有用。

在面向对象的概念中,我们知道所有的对象都是通过类来描绘的,但是反过来却不是这样。并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。

抽象类往往用来表征我们在对问题领域进行分析、设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。比如:如果我们进行一个图形编辑软件的开发,就会发现问题领域存在着圆、三角形这样一些具体概念,它们是不同的,但是它们又都属于形状这样一个概念,形状这个概念在问题领域是不存在的,它就是一个抽象概念。正是因为抽象的概念在问题领域没有对应的具体概念,所以用以表征抽象概念的抽象类是不能够实例化的。在面向对象领域,抽象类主要用来进行类型隐藏。我们可以构造出一个固定的一组行为的抽象描述,但是这组行为却能够有任意个可能的具体实现方式。这个抽象描述就是抽象类,而这一组任意个可能的具体实现则表现为所有可能的派生类。模块可以操作一个抽象体。由于模块依赖于一个固定的抽象体,因此它可以是不允许修改的;同时,通过从这个抽象体派生,也可扩展此模块的行为功能。熟悉OCP的读者一定知道,为了能够实现面向对象设计的一个最核心的原则OCP(Open-Closed Principle),抽象类是其中的关键所在。

java方法中变量用final修饰对性能有影响!你觉得呢?

在java中使用final修饰类型(包括类和接口)或类的成员与修饰方法中的普通变量从JVM的角度上看是不一样的!鉴于你谈论的是用其修饰方法中普通变量的形式,故简单说一下这方面的东东。

是否使用final修饰方法中普通变量对JVM来说没有区别!使用final修饰方法中普通变量主要是为了给Java前端编译器(如javac)看的!也就是说方法中被final修饰的普通变量在前端编译时被javac检查并保证该变量不会在作用域内被改变新值,但被编译成字节码后用于修饰方法中普通变量的final就已经不存在了!说的再具体点就是你用或不用final修饰方法中普通变量而生成的字节码文件(.class文件)没有区别(建议你用某种Class文件编辑器查看一下)!!! 当然在编译过程中会扫描final关键字并对其生成词法单元(Token),同时生成的抽象语法树(AST)在未优化之前也是有区别的。

故如你所说的“普通方法中变量用final修饰的,方法结束后jvm是不会回收这个变量的,也就不会释放内存!”这个要看该变量的作用域(比如是否发生常见的方法或线程逃逸等情况)以及是否赋值为字面量(比如字符串字面量"XXX"在加载时会被拘留(intern)在运行时常量池中,而不会在方法结束后下次GC时被回收,但这与final修饰无关!) 等特殊情况,但其是否被回收与是否仅被final修饰无关!!

至于用final修饰类型(包括类和接口)或类的成员从JVM角度考虑就和上面的很不一样了,比如你谈到的被final修饰的方法,虽然从虚拟机规范层面上讲也使用invokevirtual字节码调用,但其实它已经属于非虚方法,在JVM的角度上完全可以(当然还要看具体JVM如何实现)用指向目标方法对象的指针来作为解析的结果(直接引用),而不用再通过虚方法表进行每次执行时的动态分派过程,从而提高运行效率。再比如你谈到的内联,就我所知不用final修饰的方法在运行时只要JVM判断其满足一定条件(比如常见的HotSpot虚拟机对“热点”方法的判断)时也会根据具体情况进行内联(守护内联机制或内联缓存机制)这种基础优化机制,这方面就不多说了。(有些跑题了,呵呵)

最后想说的就是不推荐仅为了有可能提高的一点执行效率而尽可能多的使用或者滥用final(同样也适用于static等关键字),首先提升程序执行效率应该更多的从算法复杂度、业务流程合理性、软件架构合理性以及后期运行时环境调优上着手,而仅从某种语法内部运行机制上打主意意义不大!当然《Effective Java》中还是给出了不少关于使用java方面有意义的指引。其次不同的JVM产品或相同JVM产品不同版本或相同版本不同JVM配置参数都可能对同一语法机制在内部有不同的运行策略,很有可能原本希望提升执行效率的手段在某种运行时环境下却成了瓶颈。再者就算不考虑代码的可读性和可维护性,但在注释时又如何去说明仅为了提升性能而用的final或其他关键字呢?(当然可以忽视掉对它们的注释,我想这也是造成楼主提问的原因。)

罗嗦了一大堆,也不知是否是你想谈论的,希望对彼此有帮助吧。

个人看法,属于原创,仅供参考,水平有限,错误难免,接受指正,谢谢。

java非虚方法的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于JAVA虚函数、java非虚方法的信息别忘了在本站进行查找喔。