Java 重写小结

重写

父类的方法被子类继承后,为了更恰当的描述子类的行为特征,子类重新定义父类的方法,这种对父类方法进行改写或改造的现象叫做方法重写或方法覆盖;

public class Father {
	public void work() {
		System.out.println("正在上班......");
	}
}


public class Son extends Father{
	public void work() {  //子类重写父类的 work 方法
		System.out.println("正在上学......");
	}
	public static void main(String[] args) {
		Son son = new Son();
		son.work();
	}
}

正在上学......

不能重写的情况

一般情况下父类的方法都可以被子类重写,但是有几种情况例外:

public class Father {
	public static void work() {
		System.out.println("正在上班......");
	}
}


public class Son extends Father{
	public void work() {  //这里报错,父类静态方法子类无法重写
		System.out.println("正在上学......");
	}
	public static void main(String[] args) {
		Son son = new Son();
		son.work();
	}
}

当父类的方法是静态方法(即被static修饰)时,子类不能重写父类方法,即使子类同样也加上static也不是重写,只是新定义了子类的一个静态方法;

public class Father {
	public static void work() {
		System.out.println("正在上班......");
	}
}

public class Son extends Father{
	@Override 
	public static void work() {  //因为有 Override,这里还是报错
		System.out.println("正在上学......");
	}
	public static void main(String[] args) {
		Son son = new Son();
		son.work();
	}
}

@Override 是用来判断子类一个方法是否重写了父类的方法,上例代码中虽然子类的静态方法和父类的很接近,但也不是重写,只是简单的定义了一个静态方法而已;

当父类的方法被 final 修饰时,子类只能继承该方法而不能重写该方法;

public class Father {
	public final void work() {
		System.out.println("正在上班......");
	}
}

public class Son extends Father{
	/*public void work() {  //不注释掉会报错
		System.out.println("正在上学......");
	}*/
	public static void main(String[] args) {
		Son son = new Son();
		son.work();
	}
}

正在上班......

上例中注释掉的部分如果不被注释,则会报错,因为无法重写,但是,根据执行结果我们可以发现,虽然父类中被 final 修饰的方法子类不能重写,但是可以继承并使用;

public class Father {
	public void work() {
		System.out.println("正在上班......");
	}
}

public class Son extends Father{
	public void work() {
		super.work();
		System.out.println("正在上学......");
	}
	public static void main(String[] args) {
		Son son = new Son();
		son.work();
	}
}

正在上班......
正在上学......

如果想要调用已被子类重写的父类的方法,可以使用 super 关键字调用, super 还可以用在非静态代码块中,切记,不可用在静态代码块中。

重写时要注意

  1. 子类重写的方法名要与父类被重写的方法名相同,且参数列表(参数类型和参数个数)也要相同;
  2. 子类重写父类方法时不得增加 static 修饰符;
  3. 返回值:a、当父类方法的返回值类型为 void 或者为基本数据类型,则子类重写方法的返回值类型要与父类被重写方法返回值类型相同;b、当父类方法的返回值类型为引用数据类型,则子类重写方法的返回值类型要与父类被重写的方法的返回值类型相同或者是其子类;
  4. 访问控制符;子类重写方法的访问控制符不能缩小父类被重写方法的访问控制符范围,即子类重写方法的访问控制符必须大于或等于父类被重写方法的访问控制符。

 

 

深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
Java多线程是指在一个Java程序中同时执行多个线程,每个线程都是独立的执行流。Java中创建线程的方式有三种:继承Thread类、实现Runnable接口和实现Callable接口。每种方式都有其优缺点。 1. 继承Thread类创建线程类: ```java class MyThread extends Thread { public void run() { // 线程执行的代码 } } // 创建线程对象并启动线程 MyThread thread = new MyThread(); thread.start(); ``` 优点:简单易用,可以直接重写Thread类的run()方法。 缺点:由于Java不支持多继承,继承了Thread类就无法再继承其他类。 2. 实现Runnable接口创建线程类: ```java class MyRunnable implements Runnable { public void run() { // 线程执行的代码 } } // 创建线程对象并启动线程 Thread thread = new Thread(new MyRunnable()); thread.start(); ``` 优点:避免了单继承的限制,可以继续继承其他类或实现其他接口。 缺点:需要额外创建Thread对象,并将Runnable对象作为参数传递给Thread对象。 3. 实现Callable接口创建线程类: ```java class MyCallable implements Callable<Integer> { public Integer call() throws Exception { // 线程执行的代码 return 0; } } // 创建线程池对象 ExecutorService executor = Executors.newFixedThreadPool(1); // 提交Callable任务并获取Future对象 Future<Integer> future = executor.submit(new MyCallable()); // 获取线程执行结果 int result = future.get(); ``` 优点:可以获取线程执行的结果,并且可以抛出异常。 缺点:相对于前两种方式,使用Callable需要更多的代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值