C++与JAVA的语法差异

C++与JAVA的语法差异一 差异点 1 规范标准 JAVA 中的对象都是 new 出来的 只要创建对象 就会在堆中开辟一块新的空间方法实在栈中执行的 因此只要调用方法 就会在栈区开辟一块空间来执行该方法引用类型 数组 类 接口 传递的时地址值问题点 子类

大家好,欢迎来到IT知识分享网。

一、差异点

1. 规范标准

  1. JAVA中的对象都是new出来的,只要创建对象,就会在堆中开辟一块新的空间
  2. 方法实在栈中执行的,因此只要调用方法,就会在栈区开辟一块空间来执行该方法
  3. 引用类型(数组,类,接口)传递的时地址值
    在这里插入图片描述
    问题点:子类调用父类构造方法的方式有哪些?初始化父类的方式有哪些?
public class ClassName{ 
    //成员变量 private //构造方法 //无参构造方法【必须】 //满参构造方法【建议】 //getXxx() //setXxx() //成员方法  } 

2. 权限修饰符

在这里插入图片描述

3. 查看API

能够知道帮助文档的使用步骤 打开api 点击显示 点击索引,在输入框中输入要查找的内容 查看包 查看类的解释说明 查看类的构造方法 查看类的成员方法 

3. 匿名对象

匿名对象只能使用一次,作用域在也只在当前行

package OO.test class Student { 
    public String name; public int age; public void show() { 
    System.out.println(name + age); } } public class Test { 
    public static void main(String[] args) { 
    new Student("哈哈哈", 18).show(); } } 

4. 代码块

  1. 构造代码块:在类内部,成员方法的外部,每调用一次构造函数就会执行一次
  2. 静态代码块:在类内部,成员方法的外部,只在加载类的时候调用一次
  3. 局部代码块:在成员方法内部,提高阅读便利,节省内存空间,意义不大
  4. 执行优先级: 静态代码块 > 构造代码块 > 构造方法
    public class Test { 
          private int a = 0; { 
          //构造代码块,可以记录定义了多少个对象 a++; System.out.println("构造函数被调用的次数:" +a); } static { 
          //静态代码块,只被调用一次,如驱动加载等场景 System.out.println("静态代码块"); } public static void main(String[] args) { 
          { 
          //局部代码块,提高阅读性,代码块结束即释放内部变量 int a = 10; int b = 20; } } } 

5. 反射

获取类对象
一个类的Class对象都只有一个。

// 1.方式一:通过类名.class获得 Class<Student> c1 = Student.class; // 2.方式二:通过对象名.getClass()方法获得 Student stu = new Student(); Class<? extends Student> c2 = stu.getClass(); // 3.方式三:通过Class类的静态方法获得: static Class forName("类全名") Class<?> c3 = Class.forName("com.itheima.demo2_Class对象的获取.Student"); //:一个类只有一个字节码对象(Class对象) System.out.println(c1 == c2);// true System.out.println(c1 == c3);// true 

获取成员属性

Class类中与Field相关的方法 * Field getField(String name); * 根据成员变量名获得对应Field对象,只能获得public修饰 * Field getDeclaredField(String name); * 根据成员变量名获得对应Field对象,包括publicprotected(默认)private* Field[] getFields(); * 获得所有的成员变量对应的Field对象,只能获得public* Field[] getDeclaredFields(); * 获得所有的成员变量对应的Field对象,包括publicprotected(默认)private

获取构造方法

Class类中与Constructor相关的方法 1. Constructor getConstructor(Class... parameterTypes) * 根据参数类型获得对应的Constructor对象。 * 只能获得public修饰的构造方法 2. Constructor getDeclaredConstructor(Class... parameterTypes) * 根据参数类型获得对应的Constructor对象 * 可以是publicprotected(默认)private修饰符的构造方法。 3. Constructor[] getConstructors() 获得类中的所有构造方法对象,只能获得public4. Constructor[] getDeclaredConstructors() 获得类中的所有构造方法对象 可以是publicprotected(默认)private修饰符的构造方法。 Constructor对象常用方法 1. T newInstance(Object... initargs) 根据指定的参数创建对象 2. void setAccessible(true) 设置"暴力反射"——是否取消权限检查,true取消权限检查,false表示不取消 

获取成员方法

Class类中与Method相关的方法 * Method getMethod(String name,Class...args); * 根据方法名和参数类型获得对应的构造方法对象,只能获得public* Method getDeclaredMethod(String name,Class...args); * 根据方法名和参数类型获得对应的构造方法对象,包括publicprotected(默认)private* Method[] getMethods(); * 获得类中的所有成员方法对象,返回数组,只能获得public修饰的且包含父类的 * Method[] getDeclaredMethods(); * 获得类中的所有成员方法对象,返回数组,只获得本类的,包括publicprotected(默认)private

执行成员方法

Method对象常用方法 * Object invoke(Object obj, Object... args) * 调用指定对象obj的该方法 * args:调用方法时传递的参数 * void setAccessible(true) 设置"暴力访问"——是否取消权限检查,true取消权限检查,false表示不取消 

实例

class ReflectTest{ 
    //通过类加载器,加载配置文件 ClassLoader classLoader = ReflectTest.class.getClassLoader(); //获取当前类的类加载器 InputStream is = classLoader.getResourceAsStream("properties"); //获取配置文件输入流 Properties pro = new Properties(); //创建配置文件对象 pro.load(is); //加载配置文件到配置文件的对象 //获取配置文件中数据 String className = pro.getProperty("className") //获取配置文件中的类名 String methodName = pro.getProperty("methodName"); //获取配置文件中的方法名 //使用获取的数据 Class cls = Class.forName(className); //将获取的类名加载到内存 Object obj = cls.newInstance(); //获取类的对象 Method method = cls.getMethod(methodName); //获取对象的方法 method.invoke(obj, "abc"); //传入参数执行方法 } 

二、面向对象

1. 继承

  1. Java是单继承,不允许继承多个类,使用extends关键字继承
  2. 构造方法不可以被继承,私有成员可以被继承,但不能被访问
  3. 非私有成员,子类对象会优先访问子类中找
  4. Java中没有virtual关键字,因此将C++中重写和重定义都合并成了重写,即在子类中重新实现父类中的函数,重写也可以作用在多态。
  5. 重写的方法权限要>=父类的方法权限,且使用@Override注解,可以校验也可以提高代码可读性
class Fu { 
    private String name; private int age; public void show() { 
    System.out.println("这是父类"); } } class Zi extends Fu{ 
    @Override public void show() { 
    System.out.println("这是子类"); } } public class Test { 
    public static void main(String[] args) { 
    Zi zi = new Zi; zi.show(); //这是子类,(继承) Fu zi = new Zi; zi.show(); //这是子类,(多态) } } 

2. 关键字

this:存储的“当前对象”的引用;

class Cls { 
    Cls(String name, int age) { 
    System.out.println("有参构造") } Cls() { 
    this("haha", 18); //调用有参构造函数 System.out.println("无参构造") } } 

super:存储的“父类对象”的引用;

class FU { 
    public String name = "haha"; public int age = 18; public FU() { 
    System.out.println("父类无参构造"); } public FU(String name, int age) { 
    System.out.println("父类有参构造"); } } class Zi extends FU { 
    public Zi(){ 
    System.out.println("子类无参构造"); } public Zi(String name, int age) { 
    super(name, age); //调用父类有参构造 System.out.println("子类有参构造"); } } 

final:同const

final关键字就是C++中的const关键字:修饰的类不能被继承,修饰的方法不能被重写,修改时的变量只能赋值一次

3. 抽象类

  1. 被abstract关键子修饰的类就是抽象类,被修饰的方法就是抽象方法。
  2. 抽象类无论是否有抽象方法,都无法实例化;若类中有抽象方法,则必须定义成抽象类。
  3. Java中的抽象类与C++中是相同的概念,区别只是修改的关键字是abstract而非virtual,名字是抽象方法而非虚函数
abstract class Fu { 
    int a; public Fu(){ 
   } public abstract void absFunc(); } class Zi extends Fu{ 
    @Override public void absFunc() { 
    //重写父类 int b = 10; } } 

模板设计模式:模板已经定义了通用架构,使用者只需要关心自己需要实现的功能即可!

public abstract class Driver { 
    public void driveCar(){ 
    System.out.println("开门"); System.out.println("点火"); ziShi(); System.out.println("刹车"); System.out.println("熄火"); } public abstract void ziShi(); } public class NewDriver extends Driver { 
    @Override public void ziShi() { 
    System.out.println("双手紧握方向盘"); } } public class OldDriver extends Driver { 
    @Override public void ziShi() { 
    System.out.println("右手握方向盘左手抽烟"); } } public class Test { 
    public static void main(String[] args) { 
    // 创建新司机对象 NewDriver d1 = new NewDriver(); d1.driveCar(); // 创建老司机对象 OldDriver d2 = new OldDriver(); d2.driveCar(); } } 

4. 接口

定义

  1. 在JDK 7之前,java中的接口除了语法之外,同C++中的接口没有区别,接口类中只可以定义抽象方法和public static final修饰的常量,JDK8添加了默认方法和静态方法,JDK9添加了私有方法。
  2. 接口使用interface而非class,也会被编译成.class,但其本身不是类,而是另一种引用数据类型(数组、类、接口)
  3. 接口中的静态方法不可以被继承,而类中时可以被继承的
public interface IA { 
    public static final int NUM1 = 10; //常量 int NUM2 = 20; public abstract void method1(); //凑想方法 public default void method2() { 
   } //默认方法 public static void method3() { 
   } //静态方法 private void method4(){ 
   } //私有方法 } 

实现

  1. 接口只能通过implements来实现类,不能实例化,所以和抽象类很类似
  2. 接口可以多继承,实现类可以多实现,也可以多实现+继承。
public interface IA { 
    public void show1(); //无论加不加abstract关键字,都会默认为抽象方法 } public interface IB { 
    public void show2(); } public interface IC extends IA, IB { 
    //接口多继承 } class Fu { 
    public void show3(); } public class Zi extends Fu implements IA, IB { 
    //先继承,后实现 } 

多继承、多实现、继承与实现冲突时

public interface IA { 
    public static final int NUM1 = 10; //常量 int NUM2 = 20; public abstract void method1(); //凑想方法 public default void method2() { 
   } //默认方法 public static void method3() { 
   } //静态方法 private void method4(){ 
   } //私有方法 } public interface IB { 
    public static final int NUM1 = 10; //常量 int NUM2 = 20; public abstract void method1(); //凑想方法 public default void method2() { 
   } //默认方法 public static void method3() { 
   } //静态方法 private void method4(){ 
   } //私有方法 } class Fu { 
    public static final int NUM1 = 10; //常量 int NUM2 = 20; public abstract void method1(); //凑想方法 public default void method2() { 
   } //默认方法 public static void method3() { 
   } //静态方法 private void method4(){ 
   } //私有方法 } 
  1. 接口多实现时冲突
    公有静态常量会编译报错,公有抽象方法只需重写一个,公有默认方法需要重写最终版本,公有静态方法无法继承不冲突,私有方法只能在本接口中用不冲突
  2. 接口多继承时冲突
    公有静态常量会编译报错,公有抽象方法只需重写一个,公有默认方法需要重写最终版本,公有静态方法无法继承不冲突,私有方法只能在本接口中用不冲突
  3. 继承又实现时冲突
    公有静态常量会编译报错,公有抽象方法只需重写一个,公有默认方法优先访问父类默认方法,公有静态方法只会访问父类静态方法,私有方法不冲突

注意:子类重写默认方法时要加default,实现类实现默认方法时不需要加default

5. 多态

概念

  1. 静态方法无法实现多态
  2. 多态的形式分为普通多态,抽象父类多态,父接口多态
interface IA { 
   } class Fu { 
   } abstract class Fu1{ 
   } class Zi extends Fu implements IA{ 
   } class Zi extends Fu1{ 
   } class Zi implements IA{ 
   } public class Demo{ 
    public static void main(String[] args){ 
    IA c = new Zi(); //父接口 Fu c = new Zi(); //普通父类  Fu1 c = new Zi(); //抽象父类 } 

使用场景:将指向子类的父类对象作为变量、参数、返回值,此时无法调用子类的独有的方法及属性。

类型转换

子类对象转父类对象可以自动转换,父类对象转子类对象需要强制转换,强转之前可以用instanceof关键字来判断是否可以强转。

Animal anl = new Dog(); //自动转换 Dog dog = (Dog)anl; //强制转换 Animal anl = new Animal (); Dog dog = (Dog)anl; //会报错,父类转子类时,父类的对象一定要指向子类 //使用instanceof判断是否可以强转 if(anl instanceof Dog) { 
    //注意:Dog是类名而非对象名 Dog dog = (Dog)anl; } 

6. 内部类

  1. 将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类
  2. 内部类可以直接访问外部类的成员,包括私有成员。外部类要访问内部类的成员,必须要建立内部类的对象。
class Body { 
    private int num = 10; class Heart{ 
    //内部类 private int num1 = 100; public int show() { 
    return num; //直接访问外部类的私有成员 } } public int show1() { 
    return num1; //会报错,无法直接访问 } } public class Test { 
    public static void main(String[] args) { 
    Body.Heart hb = new Body().new Heart() //定义内部类对象  } } 

匿名内部类

interface IA { 
    public abstract void show1(); } class Fu() { 
    public abstract void show2(); } public class Test { 
    public static void main(String[] args) { 
    method(new IA() { 
    //创建匿名内部类 @Overrite public void show1() { 
    int i = 10; } ); method(new Fu() { 
    //创建匿名内部类 @Overrite public void show2() { 
    int i = 10; } ); } public void method(IA ia) { 
    //需要传入实现类对象 ia.show1(); } public void method(Fu fu) { 
    //需要传入子类对象 fu.show2(); } } 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/144163.html

(0)
上一篇 2025-04-28 17:15
下一篇 2025-04-28 17:20

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信