C++与JAVA的语法差异

一、差异点

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:存储的“当前对象”的引用;

this可以访问:本类的成员属性、成员方法、构造方法;
this()可以在本类的一个构造函数中调用另一个构造方法,但必须在函数中是第一行。

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

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

super可以访问:父类的成员属性、成员方法、构造方法;
子类的构造方法默认会调用父类的空构造方法,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();
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值