我在理解java中的受保护访问修饰符(或其背后的设计)时遇到了一些麻烦.我认为这意味着包访问和访问通过继承包含抽象成员的类的对象.
我写了以下示例代码.我看到如果取消注释,注释掉的行会产生编译错误.为什么我可以通过Second中的Second对象访问pro,但不能通过Second中的First对象访问pro?
package first;
public class First {
protected void pro(){
System.out.println("Can see protected method");
}
}
Run Code Online (Sandbox Code Playgroud)
package first;
public class InFirst {
public static void main(String[] args){
First fst = new First();
fst.pro();
}
}
Run Code Online (Sandbox Code Playgroud)
package second;
import first.First;
public class Second extends First {
public static void main(String[] args){
First fst = new First();
// fst.pro();
Second sec = new Second();
sec.pro();
}
}
Run Code Online (Sandbox Code Playgroud) 抽象类和只有受保护构造函数的类之间有什么区别?它们似乎与我非常相似,因为你无法实例化任何一个.
编辑:
如何在派生类中创建实例,并使用带有受保护构造函数的基类?例如:
public class ProtectedConstructor
{
protected ProtectedConstructor()
{
}
public static ProtectedConstructor GetInstance()
{
return new ProtectedConstructor(); // this is fine
}
}
public class DerivedClass : ProtectedConstructor
{
public void createInstance()
{
ProtectedConstructor p = new ProtectedConstructor(); // doesn't compile
}
public static ProtectedConstructor getInstance()
{
return new ProtectedConstructor(); // doesn't compile
}
}
Run Code Online (Sandbox Code Playgroud) 我在学习Scala时遇到了困难.我有一个继承层次结构,基本上等同于:
class A {
protected def myMethod() = println("myMethod() from A")
}
class B extends A {
def invokeMyMethod(a: A) = a.myMethod()
}
Run Code Online (Sandbox Code Playgroud)
但是尝试编译这个示例,我得到错误"test.scala:7:error:方法myMethod无法在A中访问".
来自Java,我的理解是受保护的成员应该可以在派生类的任何位置访问,而且我在任何地方都看不到任何告诉我Scala中的受保护成员受实例限制的内容.有没有人对此有解释?
这是一个让我烦恼的代码示例:
class Base {
protected:
virtual void foo() = 0;
};
class Derived : public Base {
private:
Base *b; /* Initialized by constructor, not shown here
Intended to store a pointer on an instance of any derived class of Base */
protected:
virtual void foo() { /* Some implementation */ };
virtual void foo2() {
this->b->foo(); /* Compilator sets an error: 'virtual void Base::foo() is protected' */
}
};
Run Code Online (Sandbox Code Playgroud)
您如何访问受保护的覆盖功能?
谢谢你的帮助.:O)
我正在将一些Java代码移植到C#,我遇到了这个用于复制对象的习惯用法:
class Base
{
int x;
public Base(int x) { this.x = x; }
protected Base(Base other) { x = other.x; }
}
class Derived : Base
{
Base foo;
public Derived(Derived other)
: base(other)
{
foo = new Base(other.foo); // Error CS1540
}
}
Run Code Online (Sandbox Code Playgroud)
错误CS1540是:
无法通过类型为"Base"的限定符访问受保护成员'Base.Base(Base)'; 限定符必须是'Derived'类型(或从中派生)
我理解这个错误的目的:它阻止访问兄弟类型的受保护成员.但Base.Base(Base)显然不会在兄弟类型上调用!这根本没有包含在规范中,或者我错过了为什么这不安全的原因?
编辑:嘎,成语new Base(other.foo)不是new Base(other)
作为一个(迂腐的)初学Java程序员,我想知道,将所有子类使用的公共代码块移动到父类中的单独的受保护(最终)方法是一种好习惯吗?使用常用值填充列表或常用过滤算法等任务...是否也可以使用受保护的静态方法?
class A {
protected final List<String> getVariants() {...}
protected final List<String> filterResults(List<String> variants) {...}
}
class B extends A {
public List<String> doSomethingUsefull() {
List<String> commonVariants = getVariants();
...
return filterResults(commonVariants);
}
}
class C extends A {
public void doSomethingUsefull() {
List<String> commonVariants = getVariants();
...
return filterResults(commonVariants);
}
public void doMoreUsefullThings() {
List<String> commonVariants = getVariants();
...
return filterResults(commonVariants);
}
}
Run Code Online (Sandbox Code Playgroud) 我尝试回答使用带有ISA切换的UITableViewController的UITableView子类,如下所示:
self.tableView->isa = [MyTableView class];
Run Code Online (Sandbox Code Playgroud)
但是,我收到编译错误: Instance variable 'isa' is protected.
有办法解决这个问题吗?如果是这样,这样做是否安全?
我问,因为@AmberStar对这个问题的回答似乎有些缺陷.(见我的评论.)
(这个问题是C#访问派生类中受保护成员的后续行动)
我有以下代码片段:
public class Fox
{
protected string FurColor;
private string furType;
public void PaintFox(Fox anotherFox)
{
anotherFox.FurColor = "Hey!";
anotherFox.furType = "Hey!";
}
}
public class RedFox : Fox
{
public void IncorrectPaintFox(Fox anotherFox)
{
// This one is inaccessible here and results in a compilation error.
anotherFox.FurColor = "Hey!";
}
public void CorrectPaintFox(RedFox anotherFox)
{
// This is perfectly valid.
anotherFox.FurColor = "Hey!";
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我们知道私有和受保护的字段是私有的并且受类型保护,而不是实例.
我们也知道访问修饰符应该在编译时工作.
所以,这里有一个问题 - 为什么我不能访问类实例的FurColor字段?FoxRedFox RedFox …
我正在尝试在Ruby中使用我自己的访问修饰符.我有:
class Person
def initialize (first_name, last_name, age)
@first_name=first_name
@last_name=last_name
@age=age
end
def show()
puts @first_name
puts @last_name
puts @age
end
protected
def compare(other)
self.instance_variable_get(:@age)<=>other.instance_variable_get(:@age)
end
end
p1=Person.new("Some", "Body", "99")
p1.show
puts "\n"
p2=Person.new("Who", "Ever", "21")
p2.show
puts "\n"
p1.compare(p2)
Run Code Online (Sandbox Code Playgroud)
我收到错误"保护方法`比较'调用#(NoMethodError)"我试过从类中调用而没有.我在这里粘贴了没有版本.我认为可以在同一个类的其他对象上调用受保护的方法.这个错误意味着什么?我如何在这里正确使用受保护的方法?谢谢您的帮助.
我protected在搜索我的问题的解决方案时发现了使用修饰符:忽略带有单元的反射词组件ReflectionComparator
在org.unitils.reflectionassert.ReflectionComparatorFactory课堂上有签名的方法:
protected static List<Comparator> getComparatorChain(Set<ReflectionComparatorMode> modes)
但这只是特殊情况.
毕竟我们总是可以扩展这样的任何非final类,并protected使用new public修饰符"覆盖"它的静态方法.说,我们有课A:
public class A {
protected static void test() {
// do some stuff
}
}
Run Code Online (Sandbox Code Playgroud)
并希望在另一个包中使用它:
public class UseA {
private static class MyA extends A {
public static void test() {
A.test();
}
}
void useA() {
// A.test(); compile error, sure
MyA.test();
}
}
Run Code Online (Sandbox Code Playgroud)
当某些static方法被宣布为时,我将我的问题集中在一般情况上protected.我不是在询问非静态字段或方法,因为在某些情况下,类可以具有私有构造函数或具有许多特殊参数的非常复杂的构造函数.但是如果整个班级不是这样的"隐藏"静态方法的目的是什么final?这种用法是错误还是只是非常弱的"保护"?
protected ×10
c# ×3
java ×3
constructor ×2
inheritance ×2
c++ ×1
final ×1
objective-c ×1
oop ×1
private ×1
ruby ×1
runtime ×1
scala ×1
uitableview ×1