有没有办法修改子类,以便所有超类继承更改?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了有没有办法修改子类,以便所有超类继承更改?相关的知识,希望对你有一定的参考价值。

我确切的问题是我试图在我的Xamarin应用程序中为全局的所有页面添加逻辑。

也就是说,我正在尝试创建一个所有页面都继承自的“母版页”。我将页眉/页脚和导航逻辑放在这个“母版页”中,这样​​我就不必在每个页面上重写它。 ...我说“母版页”,因为Xamarin有一个叫做master-detail的页面,这不是我所说的。我在谈论您可能在ASP.NET Web窗体中使用的母版页的概念。与Xamarin最接近的类比是<ControlTemplate>,它只需要您的工作,就可以提供与您实际可能认为的母版页相同的效果。它看起来像这样:

App.xaml(母版页的正文)

...
<Application.Resources>
    <ResourceDictionary>
        <ControlTemplate x:Key="MainPageTemplate">
            <StackLayout>
                <Label Text="{TemplateBinding HeaderText}" />
                <ContentPresenter /> <!-- this is a placeholder for content -->
                <Label Text="{TemplateBinding FooterText}" />
            </StackLayout>
        </ControlTemplate>
    </ResourceDictionary>
</Application.Resources>
...

MyPage.xaml(主页面中的内容)

<!-- Translation: this page inherits from CoolApp.Views.MyMasterPage.cs -->
<Views:MyMasterPage xmlns="http://xamarin.com/schemas/2014/forms"
            xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            xmlns:Views="clr-namespace:CoolApp.Views"
            x:Class="CoolApp.Views.MyPage"
            ControlTemplate="{StaticResource MainPageTemplate}">
    <Label Text="I am the content" />
</Views:MyMasterPage>

MyMasterPage.cs(共享页眉/页脚和导航逻辑)

// it inherits from ContentPage here, which works fine. so long as your app only uses ContentPages
public class MyMasterPage : ContentPage, INotifyPropertyChanged
{
    ...
    public static BindableProperty HeaderTextProperty;

    public string HeaderText
    {
        get { return (string)GetValue(HeaderTextProperty); }
        set
        {
            HeaderTextProperty = BindableProperty.Create("HeaderText", typeof(string), typeof(SearchPage), value);
            OnPropertyChanged("HeaderText");
        }
    }
    // footer logic
    // navigation logic
    ...
}

这个母版页设置非常适合我,直到我需要使用ContentPage以外的页面类型。具体来说,我需要一个CarouselPage以完全相同的方式工作。在上面的代码中,我可以让MyMasterPage.cs继承CarouselPage而不是ContentPage,这样就可以了,除非我在两个不同的母版页中拥有全局页眉/页脚和导航逻辑。我不能把逻辑放在继承自Page的母版页中,因为那时我的页面将是Page而不是ContentPageCarouselPage。但如果我能直接修改Page那么ContentPageCarouselPage都会得到我的改变。也许这有点像这样?

enter image description here

我希望它很清楚但是如果不是我想问的问题是如何将我的页眉和页脚以及导航逻辑全部放到一个母版页中?

答案

我有与nbpeth扩展相同的推理

如果你想为你的所有页面添加一个属性(这里是MyContentPageMyCarouselPage),你可能想为每个页面创建一个主页面而不是只有一个主页面,但是将导航逻辑集中在扩展类中

你可以尝试类似下面的东西(我不保证这段代码有效,我手边没有Xamarin设置)

public static class PageExtensions
{
    public string GetMyValue(this Page page, BindableProperty headerTextProperty)
    {
        return (string)page.GetValue(headerTextProperty);
    }

    public void SetMyValue(this Page page, out BindableProperty headerTextProperty, string value)
    {
        headerTextProperty = null;
        if (page is INotifyPropertyChanged notifyPage)
        {
            headerTextProperty = BindableProperty.Create("HeaderText", typeof(string), typeof(SearchPage), value);
            notifyPage.OnPropertyChanged("HeaderText");
        }
    }
}

public class MyMasterContentPage : ContentPage
{
    // ...
    public BindableProperty HeaderTextProperty;

    public string HeaderText
    {
        get { return GetMyValue(HeaderTextProperty); }
        set { SetMyValue(out HeaderTextProperty, value); }
    }
}

public class MyContentPage : MyMasterContentPage, INotifyPropertyChanged
{
}

public class MyMasterCarouselPage : CarouselPage
{
    // ...
    public BindableProperty HeaderTextProperty;

    public string HeaderText
    {
        get { return GetMyValue(HeaderTextProperty); }
        set { SetMyValue(out HeaderTextProperty, value); }
    }
}

public class MyCarouselPage : MyMasterCarouselPage, INotifyPropertyChanged
{
}

你仍然会有一些重复的代码,但不是重复的逻辑

另一答案

我听说为超类添加功能并思考扩展。我对c#一无所知,但是,例如,在swift中你可以向现有类型添加行为。但是,这不是通过修改孩子来实现的,但是你可以给予超类新的能力。不确定这是否正是您在用例https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods中寻找的内容

以上是关于有没有办法修改子类,以便所有超类继承更改?的主要内容,如果未能解决你的问题,请参考以下文章

Java之继承

子类没有正确地从超类继承结构[重复]

深度解析:java必须掌握的知识点——类的重用

深度解析:java必须掌握的知识点——类的重用

Java中类的继承

如何取消超类对默认 Matlab 函数的覆盖